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
When you use singleton-scoped beans with dependencies on prototype beans , be aware that dependencies are resolved at instantiation time. Thus if you dependency-inject a prototype-scoped bean into a singleton-scoped bean, a new prototype bean is instantiated and then dependency-injected into the singleton bean.
However, in the case where a memory leak may occur as described above, prototype beans can be destroyed by creating a singleton bean post-processor whose destruction method explicitly calls the destruction hooks of your prototype beans.
Singleton: Only one instance will be created for a single bean definition per Spring IoC container and the same object will be shared for each request made for that bean. Prototype: A new instance will be created for a single bean definition every time a request is made for that bean.
It's because that as long as the prototype bean does not hold a reference to another resource itself, such as a database connection or a session object, it will get garbage collected as soon as all references to the object have been removed or the object goes out of scope.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With