I am new to the spring framework, started with some tutorials to learn it.
I have following files,
# MainProgram.java
package test.spring;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainProgram {
public static void main(String[] args) {
AbstractApplicationContext context =
new ClassPathXmlApplicationContext("Bean.xml");
HelloSpring obj = (HelloSpring) context.getBean("helloSpring");
obj.setMessage("My message");
obj.getMessage();
context.registerShutdownHook();
}
}
# HelloSpring.java
package test.spring;
public class HelloSpring {
private String message;
public void setMessage(String message){
this.message = message;
System.out.println("Inside setMessage");
}
public void getMessage(){
System.out.println("Your Message : " + this.message);
}
public void xmlInit() {
System.out.println("xml configured initialize");
}
public void xmlDestroy() {
System.out.println("xml configured destroy");
}
}
# Bean.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="helloSpring" class="test.spring.HelloSpring"
scope="prototype" init-method="xmlInit" destroy-method="xmlDestroy">
</bean>
</beans>
When I take scope="singleton"
my output is :
xml configured initialize
Inside setMessage
Your Message : My message
xml configured destroy
When I take scope="prototype"
my output is :
xml configured initialize
Inside setMessage
Your Message : My message
xmlDestroy()
method is called with singleton
scope bean but not with prototype
kindly help me for the following ,
Is this correct? if so, what would be possible reasons?
Also I have some queries like,
what is difference or relation between
ApplicationContext , AbstractApplicationContext and ClassPathXmlApplicationContext
xmlDestroy()
method is called with singleton scope bean but not with prototype because
Spring does not manage the complete lifecycle of a prototype bean: the container instantiates, configures, decorates and otherwise assembles a prototype object, hands it to the client and then has no further knowledge of that prototype instance. For releasing resources try to implement a custom bean post processor.
Unlike singleton beans where the spring container manages the complete life-cycle
You can have a look at this basic tutorial for differences between different contexts
Refer documentation
A singleton bean means that there is exactly one instance of that bean in the application context. That means if you do something like this:
HelloSpring obj = (HelloSpring) context.getBean("helloSpring");
obj.setMessage("My message");
System.out.printIn(obj.getMessage());
HelloSpring anotherObj = (HelloSpring) context.getBean("helloSpring");
System.out.printIn(anotherObj.getMessage());
You will see "My message" in the console output twice.
For prototype beans everytime you try to get one of those from the application context you will get a new instance so if you run the above code again the second console output will be "null".
As there is no need for the container to call a destroy method for a prototype bean, it does not and the behavior is correct.
The difference between the said classes are that they are an interface, an abstract class and a concrete class respectively, to understand better about that concepts I suggest reading the official oracle documentation for java in here Oracle Java Tutorials.
This is the expected behaviour. There is no way for Spring to know when you have finished using a prototype scope bean, so bean destruction is not managed by Spring for prototype scoped beans. From the documentation:
Although initialization lifecycle callback methods are called on all
objects regardless of scope, in the case of prototypes, configured
destruction lifecycle callbacks are not called.
See the Spring documentation for more information.
With regards to ApplicationContext
s, you can choose the one that is best-suited to your application. It depends whether you want to use XML or annotation bean configuration, and whether or not you are running in a servlet container, for example. ApplicationContext
itself is the interface at the root of the type heirarchy.
your application could ask for new instances of prototype beans every 10 milliseconds, do something with the bean, and then let it go out of scope. If Spring had to destroy() them when the application shuts down, it would have to keep a reference to every created prototype bean, preventing them to be garbage-collected, and thus causing a memory leak.
I also tried to get a destroy event of bean which's scope is "prototype".
So I read all answers above and try by their answers.
At result, I reach out that there is no way to detect a destroy even of prototype bean.
Although initialization lifecycle callback methods are called on all objects regardless of scope, in the case of prototypes, configured destruction lifecycle callbacks are not called.
see here (https://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-factory-scopes-prototype)
Please check your scope type in your spring configuration file.
If scope="prototype" then change it to scope="singleton"
<bean id="helloWorld" class="com.example.test.HelloWorld"
init-method="init" destroy-method="destroy">
<property name="message" value="Hello World!" />