Scope and Life Cycle of a Bean

Bean Scope??

Bean Scopes

There are 4 types of scope

1) Singleton: one bean for per class loader (by default scope of bean)

2) Prototype: when you are requesting to get bean

3) Request: you will get new bean as new HttpRequest

4) session: you will get new bean as new http session

How to define in XML??

To define scope of bean in xml we have scope attribute of bean tag. like


<bean name="address" class="com.sagarandcompany.BeanScopes.PrototypeIntoSingletonProblem.Address" scope="prototype">
        <property name="city" value="High Tech City"/>
        <property name="district" value="banglore"/>
 </bean>

Annotation Based?

@Scope("request");

@Scope("session");

@Scope("prototype");

..etc

New Annotation  to define scope we have like this

 

@RequestScope

@SessionScope

@PrototypeScope

How Many Instance will be created?

Subtitle

cont...

Subtitle

Injecting a Prototype Bean into a Singleton Bean Problem.
If same scoped beans are wired together there's no problem. For example a singleton bean A injected into another singleton bean B. But if the bean A has the narrower scope say prototype scope then there's a problem.
To understand the problem let's see an example. We are going to have two beans MyPrototypeBean, scoped as prototype and MySingletonBean, scoped as singleton. We will inject the prototype bean into the singleton bean. We will also access MySingletonBean via method call context#getBean(MySingletonBean.class) multiple times. We are expecting (per prototype specifications) that a new prototype bean will be created and be injected into MySingletonBean every time.
That means there's only one instance of the prototype bean within the singleton bean. Well, a prototype bean should not behave that way. There should be a new instance every time.
The problem is: spring container only creates the singleton bean MySingletonBean once, and thus only gets one opportunity to inject the dependencies into it. The container cannot provide MySingletonBean with a new instance of MyPrototypeBean every time one is needed.

To solve this problem i autowired the applicaion context in singelton bean and get bean of protoyoe type into singleton You can also do using provider... here is the way to get bean from provider....
Method-1:

public class UserService {
    private String name;
    private String email;
    private Integer age;
    @Autowired
    private Provider<Address> provider;


    public Address getAddress() {
        Address address = provider.get();
        return address;
    }
}
Method-2

public class UserService {
    private String name;
    private String email;
    private Integer age;
    @Autowired
    private ApplicationContext context;


    public Address getAddress() {
        Address address = (Address) context.getBean("address");
        return address;
    }
}

Spring Bean Life Cycle

Bean Life Cycle

How to invoke spring bean init and destroy methods in XML?

You can define initialization and destroy methods with in the spring bean. You can configure it using init-method, and destroy-method in the xml based configuration file. These are part of spring bean life cycle. The initialization method will be called immediately after bean creation, and destroy method will be called before killing the bean instance.

 
 <bean name="personService" class="com.sagarandcompany.BeanLifeCycle.initAndDestroyMethodAttribute.PersonService"
   init-method="init" destroy-method="destroy">
    <property name="name" value="Sagar"/>
    <property name="visibility" value="Sagarmal624@gmail.com"/>
    <property name="age" value="25"/>
    </bean>
public class PersonService {
    private String name;
    private String visibility;
    private Integer age;

    public void init() {
        System.out.println("calling init method after setting all values.........." + this.toString());
    }

    public void destroy() {
        System.out.println("calling this destroy method ");
    }
}
Initialization and destruction callback

org.springframework.beans.factory.InitializingBean inteface with in your spring bean. You need implement afterPropertiesSet() method, and write all initialization code with in this method.

implementing org.springframework.beans.factory.DisposableBean interface with in your spring bean. You need to implement destroy() method with in your spring bean and move all of your clean up code with in destroy() method.
<bean name="empService"
          class="com.sagarandcompany.BeanLifeCycle.InitializingBeanAndDisposableBeanInterface.EmpService">
        <property name="name" value="Sagar"/>
        <property name="visibility" value="Sagarmal624@gmail.com"/>
        <property name="age" value="25"/>
    </bean>
public class EmpService implements InitializingBean, DisposableBean {
    private String name;
    private String visibility;
    private Integer age;

    @Override
    public void afterPropertiesSet() {
        System.out.println("calling afterPropertiesSet method after setting all values.........." + this.toString());
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("calling this destroy method ");
    }
Spring bean init and destroy methods using annotations @PostConstruct and @PreDestroy

Subtitle

public class UserService {
    private String name;
    private String visibility;
    private Integer age;

    @PostConstruct
    public void postConstruct() {
        System.out.println("calling postConstruct method after setting all values.........." + this.toString());
    }

    @PreDestroy
    public void destroy() throws Exception {
        System.out.println("calling this destroy method ");
    }
}
Configure default initialization and destroy methods in all spring beans?
In case, if you have many spring beans with initialization and destory method, then you need to define init-method and destroy-method on each individual spring bean. Spring provides an alternative and flexible way to configure this. You can define only once with same method signature and you can use across all spring beans. You need to configure default-init-method and default-destroy-method attributes on the element. This example shows how to configure it.
<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.xsd"
       default-init-method="init"
       default-destroy-method="destroy"
>

    <bean name="personService" class="com.sagarandcompany.BeanLifeCycle.initAndDestroyMethodAttribute.PersonService"
          init-method="init" destroy-method="destroy">
        <property name="name" value="Sagar"/>
        <property name="visibility" value="Sagarmal624@gmail.com"/>
        <property name="age" value="25"/>
    </bean>

</beans>

Spring Bean Post Processors

BeanPostProcessor gives you a way to do some operations before creating the spring bean and immediately after creating the spring bean. ​​

 <bean class="com.sagarandcompany.BeanLifeCycle.SpringBeanPostProcessors.MyBeanInitProcessor"/>
public class MyBeanInitProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("before initialization: " + beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("after initialization: " + beanName);
        return bean;
    }

}

The IoC container calls BeanPostProcessor.postProcessBeforeInitialization() before @PostConstruct and InitializingBean.afterPropertiesSet() method, then calls BeanPostProcessor.postProcessAfterInitialization() (after custom init method).

To implement bean post processor logic, we need to create a class which implements BeanPostProcessor interface and two of its methods.

Thank You

Title Text

Subtitle

Made with Slides.com