Rajinder Menu

Injecting properties using Spel



1)Injecting Simple values (non spel and spel version)

non-spel version:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="https://www.springframework.org/schema/beans"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans-3.0.xsd
">

<bean id="myCar" class="di.spel.Car">
<property name="year" value="2013"/>
<property name="make" value="Honda"/>
</bean>
</beans>

spel version:

<bean id="myCar" class="di.spel.Car">
<property name="year" value="#{2013}"/>
<property name="make" value="#{'Honda'}"/>
</bean>

Note that string value honda is in qoutes.

2)Injecting Reference values (non spel and spel version)

non-spel version:

<beans...>
<bean id="myCar" class="di.spel.Car">
<property name="year" value="2013"/>
<property name="make" value="Honda"/>
<property name="wheel" ref="myCarWheels"/>
</bean>

<bean id="myCarWheels" class="di.spel.Wheel">
<property name="company" value="Ceat"/>
</bean>

</beans>

spel version:

<beans ...>
<bean id="myCar" class="di.spel.Car">
<property name="year" value="#{2013}"/>
<property name="make" value="#{'Honda'}"/>
<property name="wheel" value="#{myCarWheels}"/>
</bean>

<bean id="myCarWheels" class="di.spel.Wheel">
<property name="company" value="#{'Ceat'}"/>
</bean>
</beans>

Note that in

<property name="wheel" value="#{myCarWheels}"/>

we have used value  attribute instead of ref attribute to refer id of another bean.

3)Setting value to property of some other bean (spel)

<beans...>
<bean id="myFirstCar" class="di.spel.Car">
<property name="year" value="#{2013}"/>
<property name="make" value="#{'Honda'}"/>
<property name="wheel" value="#{myCarWheels}"/>
</bean>

<bean id="mySecondCar" class="di.spel.Car">
<property name="year" value="#{myFirstCar.year}"/>
<property name="make" value="#{'BMW'}"/>
<property name="wheel" value="#{myCarWheels}"/>
</bean>

<bean id="myCarWheels" class="di.spel.Wheel">
<property name="company" value="#{'Ceat'}"/>
</bean>
</beans>

4)Predefined System Variables

Spring provides a predefined variable named systemProperties by which we can access environment Properties. For example,

<property name="userName" value="#{systemProperties['user.name']}"/>

5) T Operator()

Earlier in section 3 we have seen how to use a bean name in value attribute of property tag to provide value as:

<property name="year" value="#{myFirstCar.year}"/>

Here myFirstCar is the name of some another bean.

But suppose you want to use some other class name (say java.lang.Math class) to provide value for a property then we will write it as:

<property name="some_prop" value="#{java.lang.Math.PI}"/>

or

<property name="some_prop" value="#{Math.PI}"/>

In above statements we are setting a property named some_prop to the value of PI constant defined in java.lang.Math class.

But above statements will give errors. We cannot provide a class name directly in #{} notation.

For this purpose we have to use T() operator as:

<property name="some_prop" value="#{T(java.lang.Math).PI}"/>

or

<property name="some_prop" value="#{T(Math).PI}"/>

The T() operator in spel is used to represent an object of type java.lang.Class. In above example,
T(java.lang.Math)  represents an object of type java.lang.Class which represents Math class.

Like constants we can also call static methods of a class using T() operator as:

<property name="some_prop" value="#{T(Math).abs(10)}"/>

Similarly we can use user defined classes in T() operator. Suppose we have a class which have some static variable like:

package example.spel;

public class A{
public static int y=10;
public int z=18;

...
}

then we can write it as:

<property name="some_prop" value="#{T(example.spel.A).y}"/>

But we cannot write as:

<property name="some_prop" value="#{T(example.spel.A).z}"/>

as z is not static.It will give error.

Also, if a class lies in java.lang package then we do not need to fully qualified it. But if it lies outside of it or it is a user defined class then we need to fully qualified it.

I would like to know your comments and if you liked the article then please share it on social networking buttons.


Collaborators




Earlier we have read in constructor injection and setter injection that how we can set a reference to a bean( target bean) as the value of a property of some other bean using ref attribute of <property> and <constructor-arg> tags.

Collaborator means reference to a bean i.e reference of target bean.

Instead of ref attribute we can also use ref element inside <property> and <constructor-arg> tags in order to set the value of a property to a reference of some bean. This is shown below:

Car.java
package di.collaborators;

public class Car {
    private int year;
    private String make;
    private Wheel wheel;

    /*Constructor*/
    Car(int year, String make,Wheel wheel){
     this.year = year;
     this.make = make;
     this.wheel = wheel;
 
    }
 
    void carDetails(){
        System.out.println("Make: "+make);
        System.out.println("Year: "+year);
        System.out.println("Wheel Details:");
        wheel.wheelDetails();
    }
}

Wheel.java
package di.collaborators;

public class Wheel{

    private String company;

    Wheel(String company){
    this.company = company;
    }
   
    void wheelDetails(){
        System.out.println("    Company: "+company);
    }
}

test.java
package di.collaborators;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class test{

public static void main(String args[]){
   
    ApplicationContext appContext = new ClassPathXmlApplicationContext("ApplicationContext.xml");
   
    Car myCar = (Car) appContext.getBean("myCar");
    myCar.carDetails();
   
    }
}

ApplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="https://www.springframework.org/schema/beans"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans-3.0.xsd
">

<bean id="myCar" class="di.collaborators.Car">
<constructor-arg value="2013"/>
<constructor-arg value="Honda"/>
<constructor-arg>
<!--Collaborator i.e reference to a 'Wheel' object-->
<ref  local="myCarWheels"/>
</constructor-arg>
</bean>

<bean id="myCarWheels" class="di.collaborators.Wheel">
<constructor-arg value="Ceat"/>
</bean>
</beans>

Output
Make: Honda
Year: 2013
Wheel Details:
    Company: Ceat

The ref element has three attributes namely - local, bean and parent.

'local' attribute:

When 'local' attribute of ref tag is used as :

<bean id="myCar" class="di.collaborators.Car">
<constructor-arg value="2013"/>
<constructor-arg value="Honda"/>
<constructor-arg>
<ref local="myCarWheels"/>
</constructor-arg>
</bean>

<bean id="myCarWheels" class="di.collaborators.Wheel">
<constructor-arg value="Ceat"/>
</bean>

then both the dependent bean and its dependency must be in same xml file.

Here myCar is dependent bean and myCarWheels ( target bean) is its dependency. Thus if we are using local attribute of ref tag then both myCar and myCarWheels must be declared  in same xml file. Suppose they are defined in different xml files as:

ApplicationContext.xml
<beans...>
<bean id="myCar" class="di.collaborators.Car">
<constructor-arg value="2013"/>
<constructor-arg value="Honda"/>
<constructor-arg>
<ref local="myCarWheels"/>
</constructor-arg>
</bean>
</beans>

secondAppplicationContext.xml
<beans...>
<bean id="myCarWheels" class="di.collaborators.Wheel">
<constructor-arg value="Ceat"/>
</bean>
</beans>

then you will get following error upon running the program:

Caused by: org.xml.sax.SAXParseException: cvc-id.1: There is no ID/IDREF binding for IDREF 'myCarWheels'.

'bean' attribute:

In this case where dependent bean and its dependency are not in same xml file, you should use 'bean' attribute as shown below:

ApplicationContext.xml
<beans...>
<bean id="myCar" class="di.collaborators.Car">
<constructor-arg value="2013"/>
<constructor-arg value="Honda"/>
<constructor-arg>
<ref  bean="myCarWheels"/>
</constructor-arg>
</bean>
</beans>

secondAppplicationContext.xml
<beans...>
<bean id="myCarWheels" class="di.collaborators.Wheel">
<constructor-arg value="Ceat"/>
</bean>
</beans>

test.java(changed)
package di.collaborators;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class test{

public static void main(String args[]){
   
    ApplicationContext appContext = new ClassPathXmlApplicationContext("ApplicationContext.xml","secondApplicationContext.xml");
   
    Car myCar = (Car) appContext.getBean("myCar");
    myCar.carDetails();
   
    }
}

Car.java and Wheel.java remains same as above.

Output
Make: Honda
Year: 2013
Wheel Details:
    Company: Ceat

Similarly, ref tag can also be used in <property> tags as shown below:

<bean id="myCar" class="di.collaborators.Car">
<property name="year" value="2013"/>
<property name="make" value="Honda"/>
<property name="wheel">
<ref local="myCarWheels"/>
</property>
</bean>

<bean id="myCarWheels" class="di.collaborators.Wheel">
<property name="company" value="Ceat"/>
</bean>

For using <property> tags you have to put setters and getters in Car.java and Wheel.java.


I would like to know your comments and if you liked the article then please share it on social networking buttons.


Injecting null and an empty String



This posts shows how inject null and an empty String as a value of a property of a bean.

Example.java
package example.di;

public class Example {
   
    String anEmptyString;
   
    String nullProperty;
   
    public void setAnEmptyString(String s){
        this.anEmptyString = s;
       
    }
   
    public void setNullProperty(String s){
        this.nullProperty = s;
       
    }
   
    public void display(){
        System.out.println("anEmptyString = "+ anEmptyString);
        System.out.println("nullProperty = "+ nullProperty);
    }

}

ApplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="https://www.springframework.org/schema/beans"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans-3.0.xsd
">

<bean id="example" class="example.di.Example">

<!-- Injecting an empty String -->
<property name="anEmptyString" value=""/>

<!-- Injecting null -->
<property name="nullProperty"><null/> </property>
</bean>


</beans>

test.java
package example.di;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class test{

public static void main(String args[]){
   
    ApplicationContext appContext = new ClassPathXmlApplicationContext("ApplicationContext.xml");
    Example obj = (Example) appContext.getBean("example");
   
    obj.display();
    }
}

Output
anEmptyString =
nullProperty = null


I would like to know your comments and if you liked the article then please share it on social networking buttons.


Bean Scopes - Prototype scope



In prototype scope whenever a bean is referenced (either in <property> tags or in getBean() method),  a new instance of that bean is returned instead of returning the same instance again and again.

Consider following figure.



In above figure there are four beans namely bean1, bean2, bean3 and bean4. Bean1 is defined with prototype scope and is being injected into bean2, bean3, and bean4.  Then, unlike singleton beans, each of bean 2,3 and 4 will have their own instance of bean1. Thus there would be three separate instances of bean1 instead of one common instance.

We can also check this by code as shown in following examples.

Example1: (When a bean is referenced in <property> tags)

bean1.java

package examples.beanscopes;

public class Bean1 {
   
    public void show(){
        System.out.println("This is Prototype scoped bean");
    }
}

bean2.java
package examples.beanscopes;

public class Bean2 {
   
    Bean1 memberBean;

    public void setMemberBean(Bean1 memberBean){
        this.memberBean = memberBean;
    }
   
    public Bean1 getMemberBean(){
        return memberBean;
    }
   
}

bean3.java
package examples.beanscopes;

public class Bean3 {
   
    Bean1 memberBean;

    public void setMemberBean(Bean1 memberBean){
        this.memberBean = memberBean;
    }
   
    public Bean1 getMemberBean(){
        return memberBean;
    }
   
}

bean4.java
package examples.beanscopes;

public class Bean4 {
   
    Bean1 memberBean;

    public void setMemberBean(Bean1 memberBean){
        this.memberBean = memberBean;
    }
   
    public Bean1 getMemberBean(){
        return memberBean;
    }
   
}

ApplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="https://www.springframework.org/schema/beans" 
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<bean id="prototypeBean" class="examples.beanscopes.Bean1" scope="prototype"/>

<bean id="bean2" class="examples.beanscopes.Bean2">
<property name="memberBean" ref="prototypeBean"/>
</bean>

<bean id="bean3" class="examples.beanscopes.Bean3">
<property name="memberBean" ref="prototypeBean"/>
</bean>

<bean id="bean4" class="examples.beanscopes.Bean4">
<property name="memberBean" ref="prototypeBean"/>
</bean>

</beans>

MainApp.java
package examples.beanscopes;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
    public static void main(String args[]){
        ApplicationContext ctx=new ClassPathXmlApplicationContext("resources/ApplicationContext.xml");
        Bean2 bean2Obj = (Bean2)ctx.getBean("bean2");
        Bean3 bean3Obj = (Bean3)ctx.getBean("bean3");
        Bean4 bean4Obj = (Bean4)ctx.getBean("bean4");
       
       
        if(bean2Obj.memberBean == bean3Obj.memberBean)
            System.out.println("Bean2 and Bean3 contain same instance of prototype scoped bean1");
        else   
            System.out.println("Bean2 and Bean3 DOES NOT CONTAIN same instance of prototype scoped bean1");
       
       
        if(bean3Obj.memberBean == bean4Obj.memberBean)
            System.out.println("Bean3 and Bean4 contain same instance of prototype scoped bean1");
        else   
            System.out.println("Bean3 and Bean4 DOES NOT CONTAIN same instance of prototype scoped bean1");
       
       
        if(bean2Obj.memberBean == bean4Obj.memberBean)
            System.out.println("Bean2 and Bean4 contain same instance of prototype scoped bean1");
        else   
            System.out.println("Bean2 and Bean4 DOES NOT CONTAIN same instance of prototype scoped bean1");
       
       
       
    }

}

Output:
Bean2 and Bean3 DOES NOT CONTAIN same instance of prototype scoped bean1
Bean3 and Bean4 DOES NOT CONTAIN same instance of prototype scoped bean1
Bean2 and Bean4 DOES NOT CONTAIN same instance of prototype scoped bean1

This shows that each of bean2,  3 and 4 have their own instances of bean1. Had we defined bean1 as singleton then output would be:

Bean2 and Bean3 contain same instance of prototype scoped bean1
Bean3 and Bean4 contain same instance of prototype scoped bean1
Bean2 and Bean4 contain same instance of prototype scoped bean1

Example2: (When bean is referenced in getBean() method)

bean1.java
package examples.beanscopes;

public class Bean1 {
   
    public void show(){
        System.out.println("This is Prototype scoped bean");
    }
}

ApplicationContext.java
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="https://www.springframework.org/schema/beans" 
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<bean id="prototypeBean" class="examples.beanscopes.Bean1" scope="prototype"/>

</beans>

MainApp.java
package examples.beanscopes;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
    public static void main(String args[]){
        ApplicationContext ctx=new ClassPathXmlApplicationContext("resources/ApplicationContext.xml");
        Bean1 obj1 = (Bean1)ctx.getBean("prototypeBean");
        Bean1 obj2 = (Bean1)ctx.getBean("prototypeBean");
       
       
       
        if(obj1 == obj2)
            System.out.println("Both are same instances");
        else   
            System.out.println("Both are different instances");
       
               
    }

}

Output:
Both are different instances

Here also if we had defined bean1 as singleton then output would be:

Both are same instances

Thus whenever a prototyped bean is referenced,a new instance of this prototyped bean is created and returned, instead of returning same instance again and again.

I would like to know your comments and if you liked the article then please share it on social networking buttons.


c namespace



1 (p namespace) | 2 (c namespace)


I would like to know your comments and if you liked the article then please share it on social networking buttons.


p namespace


1 (p namespace) | 2 (c namespace)

I would like to know your comments and if you liked the article then please share it on social networking buttons.


Injecting through constructors




I would like to know your comments and if you liked the article then please share it on social networking buttons.


Types of Dependency Injection


In Spring, providing the values for the properties of a bean (i.e values to its member variables) is known as property injection. The properties of a bean are known as its dependencies. So it is also known as Dependency Injection.You may know that in Spring it is the responsibilty of the container to inject the dependencies into a  bean when it creates the bean. This is also known as Inverse of Control (IOC).

Dependency Injection can be categorized into three categories :

1) Constructor injection
2) Setter Injection
3) Interface Injection

Spring supports only constructor and setter injection.

In Constructor injection values are injected using constructors of a bean and <constructor-arg> tags while in Setter injection  values are injected using setter methods of a bean and <property> tags.

Click on the links above to know more about constructor and setter dependency injection.


I would like to know your comments and if you liked the article then please share it on social networking buttons.


Injecting through <property> tag




I would like to know your comments and if you liked the article then please share it on social networking buttons.


@Autowired Annotation (Part5)




I would like to know your comments and if you liked the article then please share it on social networking buttons.


@Autowired Annotation (Part4)




I would like to know your comments and if you liked the article then please share it on social networking buttons.