Spring Tutorial


The Spring Framework is a lightweight framework for developing Java enterprise applications. It provides high performing, easily testable and reusable code. Spring handles the infrastructure as the underlying framework so that you can focus on your application.Spring is modular in design, thereby making creation, handling and linking of individual components so much easier. Spring implements Model View Container(MVC) design pattern.


Spring Basics

Spring has a layered architecture which consists of various modules. All the modules are built on top of the core container and are mostly independent. This way, the developer is free to use only the modules that are needed for the particular requirements. The modules in Spring framework are grouped into Core Container, Data Access/Integration, Web, AOP 

CORE CONTAINER

  • Core and Beans provide the most fundamental part of the framework including IOC container and Dependency Injection(DI)
  • Context provides a means to access objects in a framework-style manner. It inherits its features from the Beans module and adds support for internationalization (using, for example, resource bundles), event-propagation and resource-loading,
  • Expression Language(EL) supports setting and getting property values, property assignment, method invocation, accessing the context of arrays, collections and indexers, logical and arithmetic operators, named variables and retrieval of objects by name from Spring’s IoC container.


DATA ACCESS/INTEGRATION

  • JDBC[Java DataBase Connectivity] provides a JDBC abstraction layer
  • ORM[Object Relational Mapping] is responsible for Database access and related activities. It provides integration layers for popular object-relational mapping APIs, including JDO, Hibernate
  • OXM [Object/XML Mapping] provides an abstraction layer that supports Object/XML mapping implementations for JAXB, Castor, XMLBeans, JiBX and XStream.
  • JMS [Java Messaging Service] provides features for creating and consuming messages.
  • Transaction provides support to programmatic and declarative transaction management for classes that implement special interfaces and for all the POJOs (Plain Old Java Objects)


AOP


It is used as a replacement for EJB container and is much simpler than EJBs. The most important service provided by AOP is declarative transaction management. The AOP implementation allows the developer to define point-cuts and method interceptors to keep the ‘concerns’ apart. This clearly enables decoupling the functionality of the code that needs to be separated.

INSTRUMENTATION


It provides class instrumentation support and also class loader implementations to be used in a certain application servers. It also exposes performance and resource utilization metrics for the Spring container and thus facilitates run time control over the spring container.


WEB


The WEB module consists of Web, Web-servlet, Web-porlet, Web-struts as sub-modules.


  • Web provides the basic web-oriented integration features such as multi part file upload functionality , a web-oriented application context and the initialization of the IoC using servlet listeners and.
  • Web-Servlet contains Spring’s MVC for the web applications. It is a part of Spring’s web application development stack.
  • Web-Struts helps in integrating a Struts web tier within a Spring application.
  • Web-Portlet typically mirrors the functionality of the web-servlet module. It provides the MVC implementation for portlet environment.

Basic concepts of Spring





The basic philosophy underlying spring framework is to avoid tight coupling between various modules. The advantage of using spring framework is that it lets the developer concentrate on developing the application while the underlying spring framework takes care of transaction APIs, remote APIs, JMX APIs, JMS APIs.

Benefits of using Spring Framework

  • Works on POJOs. Hence easier for dependency injection / injection of test data.
  • With the Dependency Injection(DI) approach, dependencies are explicit and evident in constructor or JavaBean properties
  • Enhances modularity. Provides more readable codes.
  • Provides loose coupling between different modules.
  • Effective in organizing the middle-tier applications.
  • Flexible use of Dependency injection. Can be configured by XML based schema or annotation-based style.
  • Supports declarative transaction, caching, validation and formatting.

Like its other counterparts, spring framework is essentially a skeleton which provides a solid ground work around which the application can be built. The existence of this skeleton structure guides and helps the developer throughout the application development process. Likewise, spring framework has frozen spots – those places which are rigid in order to maintain the blueprint as such , and hot spots which can be contributed by the developer. In our context, hot spots mostly refer to POJOs(Plain Old Java Object).


Inversion Of Control(IoC)


The concept of coding in abstraction effectively introduces much better coding standards. Usually while dealing with very large codes, the reason contributing to rigidity of the program is that, the higher modules always depend on the lower modules for their functioning and hence modification at one place reflects badly on other unexpected areas in the code. This problem is effectively solved in spring by leaving the work of dependency injection to the underlying framework.



Aspect Oriented Programming


AOP in spring allows cross cutting of concerns. AOP is not dependent on Spring’s IOC container. The key unit of modularity in OOP(Object Oriented Programming) is the class, whereas in AOP the unit of modularity is the aspect. Spring AOP is implemented in pure java and hence does not require a separate compilation process.

 Spring Inversion Of Control


One of the core concepts in Spring is Inversion Of Control(IOC). It makes use of  BeanFactory to manage Java objects from instantiation to destruction. The IOC implements Dependency Injection, thereby facilitating loose coupling between components(POJOs). When it comes to large codes, one of the main problems at hand would be the dependencies between the various classes. Typically high level modules depend on low level modules for their values/functionalities. Here, whenever a change is required we have to face the problem of
  1. Rigidity :Changing one part of code might affect other parts of the code
  2. Fragility :One change might lead to unexpected changes from other parts
  3. Immobility :Reuse of the code is impossible because the application is so much tangled already.

Spring uses Dependency Injection[DI] as a rescue for this problem. The underlying classes are made abstract and the instantiation, management and class casting of the objects are done by the spring framework’€™s IOC container.



It is clear from the above pictorical representation, Spring container acts as a bridge between the abstract POJO classes which contains the blue print of the required model and the metadata which provides data for the POJO classes. This way, there is no dependency for classes on one another. Making the programming abstract through dependency injection is the solution for handling the above stated problems which are mainly associated with development, enhancement and maintenance of large codes.

Setter injection in Spring – example

Dependency injection in this form, injects the values to attributes inside a class through the setter methods present inside the class. A simple POJO(Plain Old Java Object) has only a set of attributes and the corresponding getters and setters. It is a unit at its simplest which does not implement any other special features. Such POJOs are made abstract parts and the dependency is avoided by setting the values from the underlying Spring framework instead of making the values depend on other units/itself.

1. Create the POJO class into which values are to be injected using setter injection


File : SimpleSetterInjection

package com.simpleCodeStuffs;
public class SimpleSetterInjection {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
    }
}


2. Define the metadata

The value for the attribute of the POJO is provided as <property name=” ” value=” ” /> thereby setting the values of these attributes through the setter method.


The values are injected into the POJO by passing the values through setter methods


File : Beans.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="simpleSetterInjection" class=
 "com.simpleCodeStuffs.SimpleSetterInjection">
<property name="message" value="SimpleCodeStuffs--Simple Setter 
Injection"/>
</bean>
</beans>


Step 3:

Write the main class to place a call to this POJO. The object(POJO) is retrieved by passing a call with getBeans(“beanId”) on the context.
File : MainClass.java

package com.simpleCodeStuffs;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainClass {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("Beans.xml");
SimpleSetterInjection obj = (SimpleSetterInjection) 
context.getBean("simpleSetterInjection");
obj.getMessage();
}
}

Constructor injection in Spring – Example

Instead of using the setter methods to inject values to attributes, the constructor of a class can be used to inject the values from outside the class. This work again, is done through the spring metadata file , as is in the case of setter injection.

** UPDATE: Spring Complete tutorial now available here.


1. Create the POJO class into which values are to be injected using setter injection


File : SimpleConstructorInjection


package com.simpleCodeStuffs;
public class SimpleConstructorInjection {
public SimpleConstructorInjection(String message){
this.message=message;
}
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
}



Note : Unlike setter injection, a constructor has to be explicitly defined for the POJO in case of constructor injection. This is because, usually a default(no parameter) constructor is taken up. But since we will be passing a value to the constructor of this POJO to instantiate it, we require a constructor whose parameters match the set of values passed from the xml.

 

2 Define the metadata


The value for the attribute of the POJO is provided as<constructor-arg value=” ” /> thereby setting the values of these attributes through the constructor.

File : Beans.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="simpleConstructorInjection" class= 
"com.simpleCodeStuffs.SimpleConstructorInjection">
<constructor-arg value="SimpleCodeStuffs--Simple Constructor Injection"/>
</bean>
</beans>



The values are injected into the POJO through the constructor of these classes

 

3. Write the main class to place a call to this POJO


File : MainClass.java


package com.simpleCodeStuffs;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainClass {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("Beans.xml");
SimpleConstructorInjection obj = (SimpleConstructorInjection) 
context.getBean("simpleConstructorInjection");
obj.getMessage();
}
}

Spring Setter injection for reference bean

In most of the cases, one of the attributes of a class(A) is a class(B) by itself. In such cases, setting values for class A would involve setting values for Class B in turn. Then, reference to the bean ID can be passed while setting the bean using Setter injection.
The basic working of spring framework is now clear. Now, we can keep doing modifications in the existing base project to further build on our understanding. Let us take up a practical scenario for the next step. One of the attributes of a class <Candidate> is another class<Address>. The value of the class Candidate depends on the value of the Class Address. i.e., there is a dependency here.





 Step 1:

Create a new classes Candidate, Address(POJOs) and define the attributes as above. For this example, simply create the setter and getter methods for each attributes, through which their values will be injected
File : Candidate.java

package com.simpleCodeStuffs;
public class Candidate {

        private String name;
        private int age;
        private Address addrs;

        public String getName() {
                return name;
        }

        public void setName(String name) {
                this.name = name;
        }

        public int getAge() {
                return age;
        }

        public void setAge(int age) {
                this.age = age;
        }

        public Address getAddrs() {
                return addrs;
        }

        public void setAddrs(Address addrs) {
                this.addrs = addrs;
        }
}

File :Address.java


package com.simpleCodeStuffs;
public class Address {

        private String doorNo;
        private String street;
        private String area;

        public String getArea() {
                return area;
        }

        public void setArea(String area) {
                this.area = area;
        }

        public String getDoorNo() {
                return doorNo;
        }

        public void setDoorNo(String doorNo) {
                this.doorNo = doorNo;
        }

        public String getStreet() {
                return street;
        }

        public void setStreet(String street) {
                this.street = street;
        }
}

Step 2:
Create the main class.

File : MainClass.java

package com.simpleCodeStuffs;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainClass {

        public static void main(String[] args) {
           ApplicationContext context = new ClassPathXmlApplicationContext(
                                "Beans.xml");
                Candidate can = (Candidate) context.getBean("candidate");
                Address add = (Address) context.getBean("address");

                System.out.println("NameÃ�  : " + can.getName());
                System.out.println("Age: " + can.getAge());
             System.out.println("Address : " + can.getAddrs().getDoorNo());
                System.out.println("t  " + add.getStreet());
                System.out.println("t  " + add.getArea());
        }
}


In case multiple xml files need to be loaded by the main class as in some cases, the bean definitions are distributed over many xml files, then the same can be loaded in the MainClass as ApplicationContext context =new ClassPathXmlApplicationContext(“Beans.xml”,”€AnotherBeans.xml”€,”€OtherBeans.xml”);

Make sure that all these xml files are loaded properly in your project classpath.



In case the beanID mentioned by the €˜ref is present in the same xml file, then it can ALSO be particularly specified as <ref local=€address€/>

File : Beans.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="candidate" class="com.simpleCodeStuffs.Candidate">
                <property name="name" value="Sandy" />
                <property name="age" value="22" />
                <property name="addrs" ref="address" />
        </bean>

     <bean id="address" class="com.simpleCodeStuffs.Address">
             <property name="doorNo" value="1-B/25" />
              <property name="street" value="KLN Street" />
              <property name="area" value="M.K Nagar, Ayapakkam" />
        </bean>
</beans>



Note : here, ‘property’ tag is used to inject values from the metadata file in case of setter injection

A bean is created corresponding to both the classes(Candidate and Address).Make changes here to add multiple property tags corresponding to the various attributes present inside each of the classes. One major difference here is, the property Address under Candidate does not have a direct value for itself, but is rather a separate bean. Hence, instead of providing value€, provide €œref€ for this property. The value provided in ref will be nothing but the beanID of the Address class. We have used setter injection to set values for the properties. Hence, we use the tag property€™ and give the value to be set (which is passed to the corresponding setter methods) as the value correspondingly.

Constructor injection for reference bean

The basic working of spring framework is now clear. Now, we can keep doing modifications in the existing base project to further build on our understanding. Let us take up a practical scenario for the next step. One of the attributes of a class <Candidate> is another class<Address>. The value of the class Candidate depends on the value of the Class Address. i.e., there is a dependency here.



In case of constructor injection, the constructor is used to inject value into the bean. Just like in normal OOP concept, the base class constructor can be used to pass values to the child class constructor.

The end result of setter and constructor injection are the same. Still at times, one might prove to be more advantageous than the other. Now, let us make small modifications to the above classes to inject the values for the attributes using the constructor.

Step 1 :

Create Candidate and Address class. Make a note to add constructors to these classes to allow constructor injection
File : Candidate.java

package com.simpleCodeStuffs;
public class Candidate {
private String name;
private int age;
private Address addrs;
public Candidate(String name,int age,Address addrs){
this.name=name;
this.age=age;
this.addrs=addrs;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Address getAddrs() {
return addrs;
}
public void setAddrs(Address addrs) {
this.addrs = addrs;
}
}



Note one small change from the setter injection tutorials in the POJO classes. A constructor has been added to both the POJOs


File : Address.java
 

package com.simpleCodeStuffs;
public class Address {
private String doorNo;
private String street;
private String area;
public Address(String doorNo, String street,String area){
this.doorNo=doorNo;
this.street=street;
this.area=area;
}
public String getArea() {
return area;
}
public void setArea(String area) {
this.area = area;
}
public String getDoorNo() {
return doorNo;
}
public void setDoorNo(String doorNo) {
this.doorNo = doorNo;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
}

In case of setter injection, we know that the property values are assigned to the attributes of the class using the setter methods. In that case, default constructor is used for creating the instance. But here in constructor injection , we explicitly pass values to the constructor of the class from the metadata. This means that an explicit constructor has to be provided in the bean classes with parameters appropriate to what is about to be passed from the configuration metadata file.



In case the parameters passed for the bean from the metadata file and the constructor parameters in the corresponding class does not match, it results in   Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘address’ defined in class path resource [Beans.xml]: Could not resolve matching constructor


Step 2 :


There is no need to make any changes in the MainClass.java. i.e., the accessing of the objects from a third party remains totally unchanged no matter the type of injection used on these classes.

File : MainClass.java

package com.simpleCodeStuffs;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainClass {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("Beans.xml");
Candidate can = (Candidate)context.getBean("candidate");
Address add = (Address)context.getBean("address");
System.out.println("Name    : "+can.getName());
System.out.println("Age     : "+can.getAge());
System.out.println("Address : "+can.getAddrs().getDoorNo());
System.out.println("t  "+add.getStreet());
System.out.println("t  "+add.getArea());
}
}


Step 3:


The obvious change required now, is in the configuration metadata xml (Beans.xml). Instead of setting values using the <property name=” ” value=” ” />(thereby calling the setter method) we can now make use of <constructor-arg> to call the constructor with the appropriate parameters.

File : Beans.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="candidate" class="com.simpleCodeStuffs.Candidate">
                <constructor-arg index="0" value="sandy" />
                <constructor-arg index="1" value="22" />
                <constructor-arg ref="address" />
        </bean>

        <bean id="address" class="com.simpleCodeStuffs.Address">
                <constructor-arg index="0" value="1-B/25" />
                <constructor-arg index="1" value="KLN Street" />
                <constructor-arg index="2" value="M.K Nagar, Ayapakkam" />
        </bean>
</beans>



Note that, ‘constructor-arg’ tag is used to inject values from the metadata file in case of constructor injection


<constructor-arg> tag has the ˜index defined to clarify on the value being passed. The value (0,1,2) of the index is in the order of the parameters being passed to the constructor. When one of the parameters to a constructor is an object(as in Address) the value for this object can not be assigned directly. In such cases, uses ref=€<beanID>(reference injection) to point that value to the actual bean (bean id=┝address”€). The value for the attributes inside Address is set inside this bean.

Constructor injection – ambiguities

We are familiar ambiguities that may arise due to  parameter type mismatch while making a call to a simple method in java. Similarly, care needs to be taken while passing values to a class using constructor injection. What about classes that contain multiple constructors with ambiguous , partially compatible dataTypes. Which exact parameters are about to match the provided constructor definition needs to be clear.
While injecting values to the properties of a bean through constructor injection, we need to make sure that the values are set as intended, on the right properties. Let us take an example.


Step 1 : Create the POJO


File : InjectionAmbiguity

package com.simpleCodeStuffs;
public class InjectionAmbiguity {
private String name;
private String score;
private int age;
//constructor 1
public InjectionAmbiguity(String name, String score,int age){
this.name=name;
this.age=age;
this.score=score;
}
//constructor 2
public InjectionAmbiguity(String name, int age, String score){
this.name=name;
this.age=age;
this.score=score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getScore() {
return score;
}
public void setScore(String score) {
this.score = score;
}
}


Step 2 : Provide the Bean definition in the xml file

File : Beans.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="ambiguity" class="com.simpleCodeStuffs.InjectionAmbiguity">
  <constructor-arg>     
                 <value>Sandy</value>   
  </constructor-arg>
    <constructor-arg>   
                 <value>200</value>     
  </constructor-arg>
    <constructor-arg>   
                 <value>22</value>      
  </constructor-arg>
</bean>
</beans>
Note :
Here I have simply assumed that the 3 property values will get set in the order they are passed to the constructor. i.e., name,Score,Age and hence constructor 1 will get called.


Step 3: Create the Main Class


File : MainClass.java

package com.simpleCodeStuffs;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainClass {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext 
("Beans.xml");
InjectionAmbiguity amb=(InjectionAmbiguity)context.getBean("ambiguity");
System.out.println("name "+amb.getName());
System.out.println("Age "+amb.getAge());
System.out.println("Score "+amb.getScore());
}
}


Step 4 : Lets check if the output is as expected






Oopsies !!!! This is because, the constructor-arg value has been passed as
 

        <constructor-arg>       
                 <value>200</value>     </constructor-arg>

This value has been converted from String to int and hence constructor 2 was called.


Step 5 :


To avoid such unexpected results, it is always better to make the constructor-arg injection as clear as possible. The use of type is adviced.

Usage of ‘type’,’index’ attributes along with ‘constructor-arg’ tag avoids ambiguity in the constructor being called

 

Beans.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="ambiguity" class="com.simpleCodeStuffs.InjectionAmbiguity">
  <constructor-arg type="java.lang.String">     
                 <value>Sandy</value>   
  </constructor-arg>
    <constructor-arg type="java.lang.String">   
                 <value>200</value>     
  </constructor-arg>
    <constructor-arg type="int">        
                 <value>22</value>      
  </constructor-arg>
  </bean>
</beans>

Basics of Bean in Spring

Beans are the fundamental entities that we will be using while dealing with Spring. We make use of Beans as a backbone for the entire concept which enhances and supports loose coupling between components.. The various scopes that a bean can take over are :-


Scope Description
Singleton Only one instance of the bean will be available per Spring IOC container. By default, a bean has singleton scope.
Prototype A new bean instance is returned, every time there is a request
Request Returns a single bean instance per HTTP request
Session Returns a single bean instance per HTTP session
globalSession Returns a single bean instance per global HTTP session

 

Ref and ref local :


We have come across scenarios wherein, one of the attributes of a class is a class by itself. In such cases, we have seen that the value to that specific attribute is passed by using the tag
<ref=”€beanIdABC”€>
Note here that in case the definition for the beanIdABC is present in the same xml file in which it is referred to, then it is enough to place the reference instead as,
<ref local=”beanIdABC”€>
It is not mandatory to make such declaration. This is simply the best practice used in order to add on to the readability of the code.

Loading multiple configuration metadata files

While dealing with large project structure, more often the bean definitions are segregated and kept in different xml files to maintain the logical/component based structure. In such cases, there is a need to load multiple xml files into the ClassPathXmlApplicationContext.

Step 1 : Consider 3 POJOs, situated in different packages.


Beans.xml has the bean definition of Amount.java
elBeans.xml has the bean definition of Address.java and Candidate.java
File : Amount.java
package com.simpleCodeStuffs;
public class Amount {
private String val;
public String getVal() {
return val;
}
public void setVal(String val) {
this.val = val;
}
public String toString(){
return ("amount bean val: "+val);
}
}

File : Address.java

package com.simpleCodeStuffs.spEL;
public class Address {
private String doorNo;
private String street;
private String area;
public Address(){
this.doorNo=null;
this.street=null;
this.area=null;
}
public Address(String doorNo, String street,String area){
this.doorNo=doorNo;
this.street=street;
this.area=area;
}
public String getArea() {
return area;
}
public void setArea(String area) {
this.area = area;
}
public String getDoorNo() {
return doorNo;
}
public void setDoorNo(String doorNo) {
this.doorNo = doorNo;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String toString(){
return ("tdoorno "+doorNo+"ntStreet "+street+"ntarea "+area);
}
}

File : Candidate.java

package com.simpleCodeStuffs.spEL;
import com.simpleCodeStuffs.Amount;
public class Candidate {
private String name;
private int age;
private Address addrs;
private String area;
private Amount amt;
public Amount getAmt() {
return amt;
}
public void setAmt(Amount amt) {
this.amt = amt;
}
public String getArea() {
return area;
}
public void setArea(String area) {
this.area = area;
}
public Candidate(){
this.name=null;
this.age=0;
this.addrs=null;
}
public Candidate(String name,int age,Address addrs){
this.name=name;
this.age=age;
this.addrs=addrs;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Address getAddrs() {
return addrs;
}
public void setAddrs(Address addrs) {
this.addrs = addrs;
}
public String toString(){
return("name" +name+ "age"+age"+"addrs "+addrs"+" amt"+amt);
}
}

Step 2 :


Notice the package and class structure. Candidate has two other class attributes of which Address is present in the same package and the definition for the corresponding bean is present in the same xml file(elBeans.xml). The class Amount is another attribute inside Candidate, but the class is present in a different package and mainly the bean definition is available in a different xml file(Beans.xml)


Also, the definition for these beans are provided in different x

Step 3 :


The bean definition for Amount is present in Beans.xml and that for Address and Candidate is present in elBeans.xml
File : Beans.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="amount" class="com.simpleCodeStuffs.Amount">
         <property name="val" value="SimpleCodeStuffs--Amount bean val" />
        </bean>
</beans>

File : elBeans.xml
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-3.0.xsd">


        <bean id="candidate" class="com.simpleCodeStuffs.spEL.Candidate">
                <property name="name" value="Sandy" />
                <property name="age" value="22" />
                <property name="addrs" ref="address" />
                <property name="amt" ref="amount" />
        </bean>


        <bean id="address" class="com.simpleCodeStuffs.spEL.Address">
                <property name="doorNo" value="SimpleCodeStuffs--doorNo" />
                <property name="street" value="SimpleCodeStuffs--street" />
                <property name="area" value="SimpleCodeStuffs--area" />

        </bean>
</beans>

Step 4: Main class


package com.simpleCodeStuffs;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.simpleCodeStuffs.spEL.Candidate;
public class MainClass {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext(new String[] {"Beans.xml",
"elBeans.xml"});
Candidate can=(Candidate)context.getBean("candidate");
System.out.println(can);
}
}

The required bean definitions for this application are scattered over two metadata files (Beans.xml and elBeans.xml). Inorder to load both these files, take up the above approach

Step 6 : Alternative approach



In case of multiple metadata files, it is always better programming approach to import the various xml files into one xml file and in turn, load this one xml file into the ClassPathXmlApplicationContext
To have a more standard approach towards development, it is better to have a single xml file to cater to all the bean definitions required. Hence, it is advisable to import all the other xml files into one combined xml file and in turn load the one xml file in our ClassPathXmlApplicationContext as a single xml file.

For this, define a new xml file under the src folder, All-Beans.xml
<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-2.5.xsd">
<import resource="Beans.xml"/>
<import resource="elBeans.xml"/>
</beans>

In case the other 2 xmls are present inside different folder structure, then mention as,

<import resource=folder.<metadataName>.xml/>

Now, load the one bean which has all other metadata imported into it in the main class.


ApplicationContext context = new ClassPathXmlApplicationContext 
("All-Beans.xml");

Bean Scopes

The scope of a particular bean decides the number of Bean instance that will be returned per request. This is decided depending on the usage of a bean and inadvently influences the life cycle of the bean.
We have already seen that the scopes of Bean supported by spring are :-



Scope Description
Singleton Only one instance of the bean will be available per Spring IOC container. By default, a bean has singleton scope.
Prototype A new bean instance is returned, every time there is a request
Request Returns a single bean instance per HTTP request
Session Returns a single bean instance per HTTP session
globalSession Returns a single bean instance per global HTTP session

 

Singleton scope


When a bean is a singleton, only one shared instance of the bean will be managed, and all requests for beans with an id or ids matching that bean definition will result in that one specific bean instance being returned by the Spring container.
To put it another way, when you define a bean definition and it is scoped as a singleton, then the Spring IoC container will create exactly one instance of the object defined by that bean definition. This single instance will be stored in a cache of such singleton beans, and all subsequent requests and references for that named bean will result in the cached object being returned.





A single instance of the “€˜singletonBean”€™ is shared and injected each time it is referenced. There is only one instance of the €˜singletonBean available per IOC container.

A bean of singleton scope can be defined as

<bean id="singletonBean" class="com.simpleCodeStuffs" scope="singleton"/>
Or it can also be defined by

<bean id="singletonBean" class="com.simpleCodeStuffs"/>

as singleton is the default scope of a bean
 

Prototype  scope


This results in creation of a new bean instance everytime a request is made with that particular beanId(say, using getBean(“€œbeanID”€) ) . A bean of prototype scope can be defined as


<bean id="prototypeBean" class="com.simpleCodeStuffs" singleton="false"/>
Or as
<bean id="prototypeBean" class="com.simpleCodeStuffs" scope="prototype"/>





The other 3 scopes in spring are used only when there is some web configuration involved in the related bean. Initial web configuration for request,session,and globalSession
For Servlet 2.4+ web container, e.g. when using JSF or Struts, you need to add the following javax.servlet.ServletRequestListener to the declarations in your web application’s deployment descriptor ‘web.xml’ file.


 <web-app>
  ...
  ..
  .
  <listener>
    <listener-class>
     org.springframework.web.context.request.RequestContextListener
    </listener-class>
  </listener>
  .
  ..
  ...</web-app>

For servlet 2.3, provide javax.servlet.Filter implementation

 <web-app>
  ..
  .
  <filter> 
    <filter-name>requestContextFilter</filter-name> 
 <filter-class>org.springframework.web.filter.RequestContextFilter 
</filter-class>
  </filter> 
  <filter-mapping> 
    <filter-name>requestContextFilter</filter-name> 
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  .
  ..</web-app>


Request scope


With the above bean definition in place, the Spring container will create a brand new instance of the
requestBean bean using the 'requestBean' bean definition every time a HTTP request is received. The 'requestBean' bean will be effectively scoped at the HTTP request level. You can change the internal state of the instance that is created , as the other requests that are also using instances created off the back of the same 'requestBean bean definition will not be seeing these changes in state since they are particular to an individual request. Once the particular request is finished processing, the bean that is scoped to the request will be discarded.

A bean of request scope can be defined as

<bean id="requestBean" class="com.simpleCodeStuffs" scope="request"/>

Session scope


With the above bean definition in place, the Spring container will create a brand new instance of the sessionScopeBean
bean using the 'sessionScopeBean' bean definition for the lifetime of a single HTTP Session.That is , you can change the internal state of the instance that is created , as the other HTTP Session instances that are also using instances created from the same 'sessionScopeBean' bean definition will not be seeing these changes in state since they are particular to an individual HTTP Session. When the HTTP Session is eventually discarded, the bean that is scoped to that particular HTTP Session will also be discarded.

A bean of session scope can be defined as


<bean id="sessionScopeBean" class="com.simpleCodeStuffs" scope="session"/>

Global session scope


The global session scope is similar to the standard HTTP Session scope, and is used only in the context of portlet-based web applications. The portlet specification defines the notion of a global Session that is shared amongst all of the various portlets that make up a single portlet web application. Beans defined at the global session scope are scoped (or bound) to the lifetime of the global portlet Session.
Note, if you are writing a standard Servlet-based web application and you define one or more beans as having global session scope, the standard HTTP Session scope will be used, and no error will be raised.
A bean of global session scope can be defined as

<bean id="globalSessionBean" class="com.simpleCodeStuffs" 
                                        scope="globalSession"/>

Bean of Singleton scope

When no explicit scope is mentioned during bean definition, it is taken by default as single.

   

Step 1: Define the POJO


File : Amount.java
package com.simpleCodeStuffs;
public class Amount {
private String val;
public String getVal() {
return val;
}
public void setVal(String val) {
this.val = val;
}
}
In singleton scope, only a single bean instance is returned per Spring IoC container


Step 2 : Define the bean definition


File : Beans.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="amount" class="com.simpleCodeStuffs.Amount">
                <property name="val" value="SimpleCodeStuffs" />
        </bean>
</beans>
Note, only the bean is defined. Property values are injected from the main class in order to provide some clarity on the subject. Also note, the scope has no€™t been mentioned in the bean definition. Therefore, the bean takes the default scope of singleton

Step 3


Create the Main class to receive the object from the beanId and place the call
File : MainClass.java

package com.simpleCodeStuffs;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.simpleCodeStuffs.Amount;
public class MainClass {
public static void main(String[] args) {
ApplicationContext context= new ClassPathXmlApplicationContext
 ("Beans.xml");
Amount Firstamt=(Amount)context.getBean("amount");
/* instance of bean returned*/
Firstamt.setVal("SimpleCodeStuffs");
System.out.println(Firstamt.getVal());
Amount Secondamt=(Amount)context.getBean("amount");
/*For singleton scope, new bean instance
is not returned at this point. Hence the same value is printed. */
System.out.println(Secondamt.getVal());
}
}

Note that, as the bean is of singleton scope, only one instance is returned for the beanID amount€™ per IOC container. This can be seen in the output as the same value is printed twice, once for Firstamt and once for Secondamt.

Bean of Prototype scope

This scope of bean can be utilised when more than one instance of a particular bean is required during the span of an application. It teturn a new bean instance each time a request is made.

Step 1 : Define the POJO


File : Amount.java

package com.simpleCodeStuffs;
public class Amount {
private String val;
public String getVal() {
return val;
}
public void setVal(String val) {
this.val = val;
}
}



In prototype scope,a new instance of the bean is returned per request. (every time getBean() method is called)


Step 2 : Define the bean definition


File : Beans.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="amount" class="com.simpleCodeStuffs.Amount" scope="prototype">
        </bean>
</beans>

Note, only the bean is defined. Property values are injected from the main class in order to provide some clarity on the subject. Also note, the scope has been mentioned as ‘prototype’ in the bean definition. Therefore, an instance of the bean will be returned every time a request is made.


Step 3 : Create the main class


File : MainClass.java

package com.simpleCodeStuffs;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.simpleCodeStuffs.Amount;
public class MainClass {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext 
("Beans.xml");
Amount Firstamt=(Amount)context.getBean("amount");
/* instance of bean returned*/
Firstamt.setVal("SimpleCodeStuffs");
System.out.println(Firstamt.getVal());
Amount Secondamt=(Amount)context.getBean("amount");
/*For PROTOTYPE scope, new bean instance is returned */
System.out.println(Secondamt.getVal());
}
}

Note that the bean is of scope “prototype”€™. So an instance of the bean is returned everytime a request is made using getBean() method. So, a new instance is returned for Secondamt and no value has been set for the new instance. This can be seen in output as Secondamt prints null value.

Working with Set,List,Map and Properties as attributes

We have seen examples of having a classA as one of the attributes of another classB.
We also have cases wherein the attributes of the class are a List of another object(classA).
Example File : Bill

public class Bill {
private List<ABC> abc;
}

File : ABC

Public class ABC{
Private double amount;
Private double discount;
}

For such cases, the value for the List or any other similar collection needs to be injected
through framework, which involves a slight syntactical change.


Step 1 :

Create the POJO which is going to be one of the attributes of another class.   File : Amount.java

package com.simpleCodeStuffs;
public class Amount {
private double bill;
public double getBill() {
return bill;
}
public void setBill(double bill) {
this.bill = bill;
}
@Override
public String toString(){
return("amount "+bill);
}
}


Step 2 :

CollectionBean is a class, which has a list,set,map,properties of another Object as its attributes. Just to enhance the understanding, we take it that CollectionBean may have a List of any Object as its attributes. Hence the attributes are defined as List of Object and likewise.
File : CollectionBean.java

package com.simpleCodeStuffs;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class CollectionBean {
        private List<String> stringListVariable;
        private List<Object> listVariable;
        private Set<Object> setVariable;
        private Map<Object, Object> mapVariable;
        private Properties propVariable;
        
        
        public List<String> getStringListVariable() {
                return stringListVariable;
        }
    public void setStringListVariable(List<String> stringListVariable) {
                this.stringListVariable = stringListVariable;
        }
        public List<Object> getListVariable() {
                return listVariable;
        }
        public void setListVariable(List<Object> listVariable) {
                this.listVariable = listVariable;
        }
        public Set<Object> getSetVariable() {
                return setVariable;
        }
        public void setSetVariable(Set<Object> setVariable) {
                this.setVariable = setVariable;
        }
        public Map<Object, Object> getMapVariable() {
                return mapVariable;
        }
      public void setMapVariable(Map<Object, Object> mapVariable) {
                this.mapVariable = mapVariable;
        }
        public Properties getPropVariable() {
                return propVariable;
        }
       public void setPropVariable(Properties propVariable) {
                this.propVariable = propVariable;
        }
}

Step 3 : Main class to print the details of the attributes


File : MainClass.java

package com.simpleCodeStuffs;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.simpleCodeStuffs.Amount;
import com.simpleCodeStuffs.CollectionBean;
public class MainClass {
         public static void main(String[] args) { 
            ApplicationContext context = 
           new ClassPathXmlApplicationContext("Beans.xml")
         CollectionBean bean=(CollectionBean)context.getBean("testBean");
         Amount amt=(Amount)context.getBean("amount"); 
      System.out.println("List of String:t"+bean.getStringListVariable()); 
         System.out.println("List          :t"+bean.getListVariable());
         System.out.println("set           :t"+bean.getSetVariable();
         System.out.println("Map           :t"+bean.getMapVariable());
         System.out.println("Properties    :t"+bean.getPropVariable());
           }
}

Step 4 :


This is the main change. For each of the collection variables, the way in which the value is injected in the configuration metadata has a syntax change.

‘list’, ‘set’,’map’,’props’ tags are used respectively for List, Set, Map and Properties collections
File : Beans.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="testBean" class="com.simpleCodeStuffs.CollectionBean">
                <property name="stringListVariable">
                        <list>
                                <value>A Simple</value>
                                <value>List</value>
                                <value>Of</value>
                                <value>String</value>
                        </list>
                </property>
                <property name="listVariable">
                        <list>
                                <value>1</value>
                                <value>List of Objects</value>
                                <ref bean="amount" />
                                <bean class="com.simpleCodeStuffs.Amount">
                                  <property name="bill">
                                               <value>45.9</value>
                                      </property>
                                </bean>
                        </list>
                </property>
                <property name="setVariable">
                        <set>
                                <value>2</value>
                                <value>Set of Objects</value>
                                <ref bean="amount" />
                                <bean class="com.simpleCodeStuffs.Amount" 
                             <property name="bill">
                                  <value>09.5</value>
                                        </property>
                                </bean>
                        </set>
                </property>
                <property name="mapVariable">
                        <map>
                                <entry key="a" value="3" />
                                <entry key="b" value="Map of Objects" />
                                <entry key="c" value-ref="amount" />
                                <entry key="d" 
                        <bean class="com.simpleCodeStuffs.Amount"> 
                                 <property name="bill">
                                    <value>76.5</value>
                                      </property>
                                        </bean>
                                </entry>
                        </map>
                </property>
                <property name="propVariable">
                        <props>
                            <prop key="a">4</prop>
                            <prop key="b">properties</prop>
                      </props>
                </property>
        </bean>

      <bean id="amount" class="com.simpleCodeStuffs.Amount">
                <property name="bill">
                        <value>56.9</value>
                </property>
        </bean>
</beans>
Injection of any variable of any kind viz., primitive data type, reference to another bean, inner bean can be done for the above Collections as shown
The first example shown, “stringListVariable” is simply to state the means by which multiple values of a simple Data type can be injected into the list. The other variables take values of type Object. Hence, first an Integer, then a String is inserted.
The third one is to show how a reference to another bean can be inserted as a value to the list/set/map. The fourth one shows how an inner bean can be defined and the value inserted to the list/set/map. Note here that, while defining an inner bean, there is no need to mention the beanId as it has limited scope to only the outer bean which defines it.

List FactoryBean, Set FactoryBean and Map FactoryBean in Spring

We have previously seen how to deal with List, Set and Map type attributes inside a bean class. Further let us venture into having concrete List collection (ArrayList and LinkedList), Set collection(HashSet and TreeSet)  Map collection(HashMap and TreeMap)

Step 1 : Create the POJO


File : ClassABC.java


package com.simpleCodeStuffs;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class ClassABC {

        private List listVariable;
        private Map mapVariable;
        private Set setVariable;

        public List getListVariable() {
                return listVariable;
        }

        public void setListVariable(List listVariable) {
                this.listVariable = listVariable;
        }

        public Map getMapVariable() {
                return mapVariable;
        }

        public void setMapVariable(Map mapVariable) {
                this.mapVariable = mapVariable;
        }

        public Set getSetVariable() {
                return setVariable;
        }

        public void setSetVariable(Set setVariable) {
                this.setVariable = setVariable;
        }

        public String toString() {
         return ("listVariable t" + listVariable + "nsetVariable t"
                    + setVariable + "nmapVariable t" + mapVariable);
        }
}
File : Amount.java


package com.simpleCodeStuffs;
public class Amount {

        private String val;

        public String getVal() {
                return val;
        }

        public void setVal(String val) {
                this.val = val;
        }

        public String toString() {
                return ("amount bean val: " + val);
        }
}


Step 2 : Provide the configuration metadata in the xml file



To support the concrete classes of List, Map and Set, it is essential to include util schema in the Beans.xml file.Else, you will end up getting a SAXParseException because of it

File : Beans.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" xmlns:
util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.5.xsd">

<bean id="abc" class="com.simpleCodeStuffs.ClassABC">
        <property name="listVariable">
              <util:list list-class="java.util.ArrayList">
                        <value>1</value>
                        <value>ArrayList</value>
                        <ref bean="amount" />
                </util:list>
        </property>

        <property name="setVariable">
             <util:set set-class="java.util.HashSet">
                        <value>2</value>
                        <value>HashSet</value>
                        <ref bean="amount" />
                </util:set>
        </property>

        <property name="mapVariable">
                <util:map map-class="java.util.HashMap">
                        <entry key="Key1" value="3" />
                        <entry key="Key2" value="HashMap" />
                        <entry key="Key3" value-ref="amount" />
                </util:map>
        </property>
</bean>
<bean id="amount" class="com.simpleCodeStuffs.Amount">
        <property name="val" value="simpleCodeStuffs" />
</bean>
</beans>


Step 3 :


File : MainClass.java

package com.simpleCodeStuffs;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainClass {
public static void main(String[] args) {
ApplicationContext context = new  
ClassPathXmlApplicationContext("Beans.xml"); 
       ClassABC abc = (ClassABC) context.getBean("abc");
       System.out.println(abc);
}
}

Using life cycle events on a bean

The life cycle events of a bean can be used to set values to the attributes of a bean using the init method.
We can associate the life cycle events of a bean to make calls to corresponding init and destroy method. The init and destroy method associated with a bean are given along with the bean definition. This way, a call is automatically made to these methods, as per the bean’s state.
Init method is called once the property of the bean is set.
Destroy method is called when the context associated with the bean is closed. This is when all the resources related to the context are cleared.

Step 1 :

Create a POJO with a method each for defining the steps to be taken at initial and destroy step. Note that the method name is user defined
File : Amount.java

package com.simpleCodeStuffs;
public class Amount {
        private String val;

        public String getVal() {
                return val;
        }

        public void setVal(String val) {
                this.val = val;
        }

        public String toString(){
                return ("amount bean val: "+val);
        }
        
        public void startUp(){
 System.out.println("init() method called after properties to 
      Amount are set. ");
             System.out.println(toString());
        }
        
        public void cleanUp(){
System.out.println("destroy method called when application 
  context is closed");
          System.out.println("Releasing/destroying all resources");
           System.out.println(toString());
        }
        }

Step 2 :

Bean definition is given along with the init and destroy values. The method names correspondingly are given here.

‘init-method’ and ‘destroy-method’ attributes are used along with the bean definition ‘bean’ tag, to specify the methods to be called during the start up and destruction stage of the bean


File : Beans.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="amount" class="com.simpleCodeStuffs.Amount" 
 init-method="startUp" destroy-method="cleanUp"> 
      <property name="val" value="SimpleCodeStuff--HelloWorld" />
        </bean>
</beans>

Step 3 : Create the main class


File : MainClass.java

package com.simpleCodeStuffs 
 import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainClass {       
 public static void main(String[] args) {
               
   ApplicationContext context = new ClassPathXmlApplicationContext(                       
 new String[] { "Beans.xml" });
              Amount amt = (Amount) context.getBean("amont");
     System.out.println("printing amount in main class " + amt);
                
        }
}
 

Notice that, the destroy method has never been called. This is because the context is not closed.

Step 5 :

Make modifications in the main class to close the context. Note,we have initially used it as

  ApplicationContext context = 
    new ClassPathXmlApplicationContext(new String[] {"Beans.xml"});
Amount amt=(Amount)context.getBean("amount");

But, close() method is not defined on ApplicationContext. The method is rather defined on the implementation ClassPathXmlApplicationContext. So let us modify that part as well  to implement our changes. Now the main class is

package com.simpleCodeStuffs;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainClass {
        public static void main(String[] args) {
      ClassPathXmlApplicationContext context =
   new ClassPathXmlApplicationContext(new String[] {"Beans.xml"});             
context.close()
//     ApplicationContext context = new ClassPathXmlApplicationContex                              
new String[] { "Beans.xml" }); 
           Amount amt = (Amount) context.getBean("amount"); 
         System.out.println("printing amount in main class " + amt);
           context.close(); // destroy method is called here
        }
}

Basics of Spring Expression Language (SpEL)

The Spring Expression Language (SpEL for short) is a powerful expression language that supports querying and manipulating an object graph at runtime and can work with all the spring framework products.There are several other Java expression languages like, OGNL, MVEL, and JBoss EL, etc. Still, the Spring Expression Language was created to provide the Spring community with a single well supported expression language that can used across all the products in the Spring portfolio. The language syntax is similar to Unified EL but offers additional features, most notably method invocation and basic string templating functionality.
Though spEL works as the foundation for expression language within spring, it is still not tied to the spring framework. Thus spEL works independently without depending on the spring framework.


The expression language supports the following functionality

  • Literal expressions
  • Boolean and relational operators
  • Regular expressions
  • Class expressions
  • Accessing properties, arrays, lists, maps
  • Method invocation
  • Relational operators
  • Assignment
  • Calling constructors
  • Bean references
  • Array construction
  • Inline lists
  • Ternary operator
  • Variables
  • User defined functions
  • Collection projection
  • Collection selection
  • Templated expressions

Basic example using spEL Basic example using spEL

Step 1 :


Create a new package, com.simpleCodeStuffs.spEL€. Create the POJO classes Candidate.java and Address.java with the below specifications.
File : Candidate.java

package com.simpleCodeStuffs.spEL;
public class Candidate {

        private String name;
        private int age;
        private Address addrs;
        private String area;

        public String getArea() {
                return area;
        }

        public void setArea(String area) {
                this.area = area;
        }

        public Candidate() {
                this.name = null;
                this.age = 0;
                this.addrs = null;
        }

        public Candidate(String name, int age, Address addrs) {
                this.name = name;
                this.age = age;
                this.addrs = addrs;
        }

        public String getName() {
                return name;
        }

        public void setName(String name) {
                this.name = name;
        }

        public int getAge() {
                return age;
        }

        public void setAge(int age) {
                this.age = age;
        }

        public Address getAddrs() {
                return addrs;
        }

        public void setAddrs(Address addrs) {
                this.addrs = addrs;
        }
}

Fie : Address.java

package com.simpleCodeStuffs.spEL;
public class Address {

        private String doorNo;
        private String street;
        private String area;
        public Address() {
                this.doorNo = null;
                this.street = null;
                this.area = null;
        }

        public Address(String doorNo, String street, String area) {
                this.doorNo = doorNo;
                this.street = street;
                this.area = area;
        }

        public String getArea() {
                return area;
        }

        public void setArea(String area) {
                this.area = area;
        }

        public String getDoorNo() {
                return doorNo;
        }

        public void setDoorNo(String doorNo) {
                this.doorNo = doorNo;
        }

        public String getStreet() {
                return street;
        }

        public void setStreet(String street) {
                this.street = street;
        }
}


Step 2 :


Under the src folder, create a new xml file €“elBeans.xml to provide the configuration metadata using spEL
File ; elBeans.xml

<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="elAddress" class="com.simpleCodeStuffs.spEL.Address">
               <property name="doorNo" value="No. 10/7" />
              <property name="street" value="North Park Street" />
                <property name="area" value="Ambattur" />
        </bean>

      <bean id="elCandidate" class="com.simpleCodeStuffs.spEL.Candidate">
                <property name="name" value="Sandy" />
                <property name="age" value="22" />
                <property name="addrs" value="#{elAddress}" />
                <property name="area" value="#{elAddress.area}" />
        </bean>
</beans>

Note here, the value for the bean œelAddress€ is provided using a simple setter injection. But for the bean elCandidate , the value for addrs and area property is provided using spEL expression.
The general syntax for a spEL expression is


#{spEL Expression}

In the above example, the value for addrs is provided as #{elAddress}. This means that addrs is assigned the value set for the bean elAddress. Similarly, for area property, the value is assigned to #{elAddress.area}, thereby injecting the value of the ‘€˜area’ property from €˜’elAddress’€™ to the €˜area property inside elCandidate€™.


Step 3 : Provide the Main Class


File : MainClass.java


package com.simpleCodeStuffs.spEL;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainClass {

        public static void main(String[] args) {

                ApplicationContext context  
                     new ClassPathXmlApplicationContext("elBeans.xml");
              Candidate can = (Candidate) context.getBean("elCandidate");
                Address add = (Address) context.getBean("elAddress")
                System.out.println("Name: " + can.getName());
                System.out.println("Age  : " + can.getAge());
                System.out.println("Area  : " + can.getArea());
             System.out.println("Address : " + can.getAddrs().getDoorNo());
                System.out.println("t " + add.getStreet());
                System.out.println("t  " + add.getArea());
        }
}