March 10, 2017

#Spring part 2 : Scopes, Bean Definition Inheritance..

Bean Scopes : While defining a we have the option of declaring a scope for that bean. Following are the five scopes (three of which are available only if you use a web-aware ApplicationContext):

1). singleton  : Its the default scope, it scopes the bean definition to a single instance per Spring IoC container. This single instance is stored in a cache of such singleton beans, and all subsequent requests and references for that named bean return the cached object.
2). prototype : If the scope is set to prototype, the Spring IoC container creates a new bean instance of the object every time a request for that specific bean is made.
3). request : New bean is created per HTTP request. Only valid in the context of a web-aware Spring ApplicationContext.
4). session : New bean is created per HTTP session. Only valid in the context of a web-aware Spring ApplicationContext.
5). global-session : This scopes a bean definition to a global HTTP session. Only valid in the context of a web-aware Spring ApplicationContext.

Does Spring Bean provide thread safety?
The default scope of Spring bean is singleton, so there will be only one instance per context. That means that all the having a class level variable that any thread can update will lead to inconsistent data. Hence in default mode spring beans are not thread-safe.

However we can change spring bean scope to request, prototype or session to achieve thread-safety at the cost of performance. It’s a design decision and based on the project requirements. 
ApplicationContextAware : Beans can get the access to the ApplicationContext object by implementing the ApplicationContextAware interface.

BeanNameAware : This interface is used to get the name of the bean configured in the Spring XML.

Bean Definition Inheritance : We can configure a parent bean definition and have children beans inherit the bean definitions. The child definition can override some values, or add others, as needed.
 e.g:

Suppose the Triangle has three points. Inside Triangle, we have declared variable pointA, pointB and pointC. For bean inheritance, inside the spring.xml, we have added reference of pointA in parenttraingle.

A new bean traingle1 is declared, with a parent tag and reference to pointB and pointC.

When you call context.getBean("traingle1"), it will return a new traingle bean which has reference to pointA, pointB and pointC beans.

 < ?xml version="1.0" encoding="UTF-8"? >
 < !DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd" >
 < beans >
     < bean id="parenttraingle" class="com.spring.test.Traingle" >
         < property name="pointA" ref="pointA" / >
     < /bean >
     < bean id="traingle1" class="com.spring.test.Traingle" parent="parenttraingle" >
         < property name="pointB" ref="pointB" / >
         < property name="pointC" ref="pointC" / >
     < /bean >
     < bean id="pointA" class="com.spring.test.Point" >
         < property name="x" value="0" / >
         < property name="y" value="0" / >
     < /bean >
     < bean id="pointB" class="com.spring.test.Point" >
         < property name="x" value="-20" / >
         < property name="y" value="0" / >
     < /bean >
     < bean id="pointC" class="com.spring.test.Point" >
         < property name="x" value="0" / >
         < property name="y" value="20" / >
     < /bean >

 < /beans >

Collection Inheritance
: Now lets suppose, Traingle has a List of Points.
import java.util.List;

public class Traingle {
    private List < Point >  points;
    public void draw()
    {
        System.out.println("Drawing traingle..");
        points.forEach((point)- > System.out.println(point));
    }
    //getters and setter for points  
}

 < ?xml version="1.0" encoding="UTF-8"? >
 < !DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd" >
 < beans >
     < bean id="parenttraingle" class="com.spring.test.Traingle" >
         < property name="points" >
             < list >
                 < ref bean="pointA" / >
             < /list >
         < /property >
     < /bean >
     < bean id="traingle1" class="com.spring.test.Traingle" parent="parenttraingle" >
         < property name="points" >
             < list >
                 < ref bean="pointB" / >
                 < ref bean="pointC" / >
             < /list >
         < /property >
     < /bean >
     < bean id="pointA" class="com.spring.test.Point" >
         < property name="x" value="0" / >
         < property name="y" value="0" / >
     < /bean >
     < bean id="pointB" class="com.spring.test.Point" >
         < property name="x" value="-20" / >
         < property name="y" value="0" / >
     < /bean >
     < bean id="pointC" class="com.spring.test.Point" >
         < property name="x" value="0" / >
         < property name="y" value="20" / >
     < /bean >
 < /beans >


If you do this, while initializing the traingle1, it will create a new list and add reference of pointB and pointC. If you want. instead of creating the new list in traingle1, it should update the existing list of parenttraingle then you have to mention 'merge' attricute.

 < bean id="traingle1" class="com.spring.test.Traingle" parent="parenttraingle" >
         < property name="points" >
             < list merge="true" >
                 < ref bean="pointB" / >
                 < ref bean="pointC" / >
             < /list >
         < /property >
 < /bean >


abstract bean: If you do not want to allow Java code to instantiate a particular bean (e.g a parent bean in our case parenttraingle), then set abstract attribute to true. . e.g:
     < bean id="parenttraingle" class="com.spring.test.Traingle" abstract="true" >
         < property name="points" >
             < list >
                 < ref bean="pointA" / >
             < /list >
         < /property >
 < /bean >  



-K Himaanshu Shuklaa..

No comments:

Post a Comment

RSSChomp Blog Directory