March 10, 2017

#Spring part 1 : Spring Framework, Bean Factory, Property Initilization, Constructor Injection, Injecting Objects, Inner Beans, Aliases, Initializing Collections and Bean Autowiring

What is Spring Framework?
Spring is one of the most widely used Java EE framework. Dependency Injection and Aspect Oriented Programming are the core concepts of Spring framework.

It can be used in normal java applications also to achieve loose coupling between different components by implementing dependency injection and we can perform cross cutting tasks such as logging and authentication using spring support for aspect oriented programming.

What are the advantages of Spring Framework?
  • Reducing direct dependencies between different components of the application, usually Spring IoC container is responsible for initializing resources or beans and inject them as dependencies.
  • Since the business logic doesn’t have direct dependencies with actual resource implementation classes, writing unit test cases are easy in Spring framework. We can easily write a test configuration and inject our mock beans for testing purposes.
  • Reduces the amount of boiler-plate code, such as initializing objects, open/close resources. I like JdbcTemplate class a lot because it helps us in removing all the boiler-plate code that comes with JDBC programming.
  • Spring framework is divided into several modules, it helps us in keeping our application lightweight. For example, if we don’t need Spring transaction management features, we don’t need to add that dependency in our project.
What do you understand by Dependency Injection (DI)?
When writing a complex Java application, application classes should be as independent as possible of other Java classes to increase the possibility to reuse these classes and to test them independently of other classes while doing unit testing. Dependency Injection helps in gluing these classes together and same time keeping them independent.

i.e Dependency Injection design pattern allows us to remove the hard-coded dependencies and make our application loosely coupled, extendable and maintainable. For example, 'DEPENDENCY' means class A is dependent on class B. 'INJECTION' signifies means that class B will get injected into class A by the IoC (Inversion of Control).

Dependency injection can happen in the way of passing parameters to the constructor or by post-construction using setter methods.


Name some of the important Spring Modules?
  • Spring Context – for dependency injection.
  • Spring AOP – for aspect oriented programming.
  • Spring DAO – for database operations using DAO pattern
  • Spring JDBC – for JDBC and DataSource support.
  • Spring ORM – for ORM tools support such as Hibernate
  • Spring Web Module – for creating web applications.
  • Spring MVC – Model-View-Controller implementation for creating web applications, web services etc.

What is Spring Bean and what are the properties of Bean?
Beans are the object that form the backbone of our application and are instantiated, assembled and managed by Spring IoC container. They are created with the configuration metadata that we supply to the container.

Bean Properties:
1). class: It's a mandatory attribute, since it specifies the bean class to be used to create the bean.
2). name: Used to uniquely identify bean. In XMLbased configuration metadata, we use the id and/or name attributes to specify the bean identifier(s).
3). scope: It specifies the scope of the objects created from a particular bean definition
4). constructor-arg: Used to inject constructor based dependencies.
5). properties: Used to inject attribute based dependencies.
6). autowiring mode
7). lazy-initialization mode: It tells the IoC container to create a bean instance when it is first requested, rather than at the startup.
8). initialization method: A callback to be called just after all necessary properties on the bean have been set by the container.
9). destruction method: A callback to be used when the container containing the bean is destroyed.

What are different scopes of Spring Bean?
  • singleton: Only one instance of the bean will be created for each container. This is the default scope for the spring beans. While using this scope, make sure spring bean doesn’t have shared instance variables otherwise it might lead to data inconsistency issues because it’s not thread-safe.
  • prototype: A new instance will be created every time the bean is requested.
  • request: This is same as prototype scope, however it’s meant to be used for web applications. A new instance of the bean will be created for each HTTP request.
  • session: A new bean will be created for each HTTP session by the container.
  • global-session: This is used to create global session beans for Portlet applications.
Read More : #Spring part 2 : Scopes, Bean Definition Inheritance.. 

What are the methods to provide configuration metadata to the Spring Container?
There are mainly three ways to provide configuration metadata to Spring IoC Container:
1). XML based configuration file: This is the most popular configuration:
 < bean name="myBean" class="com.khimaanshu.beans.MyTestBean" >  < /bean >
2). Java-based configuration: We can configure a Spring bean using @Bean annotation. This annotation is used with @Configuration classes to configure a spring bean. e.g:

@Configuration
@ComponentScan(value="com.khimaanshu.spring.main")
public class MyConfiguration {

    @Bean
    public MyTestBean getMyTestService(){
        return new MyTestBean();
    }
}

To get the MyTestBean:
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(myConfiguration.class);
MyTestBean myTestBean = context.getBean(MyTestBean.class);

3). Annotation-based configuration: We can also use @Component, @Service, @Repository and @Controller annotations with classes to configure them to be as spring bean. For these, we would need to provide base package location to scan for these classes. e.g:
< context:component-scan base-package="com.khimaanshu.spring" / >


What is Spring IoC Container?
Inversion of Control (IoC) is the mechanism to achieve loose-coupling between Objects dependencies.

In IoC, object coupling is bound at run time by an assembler object and is typically not known at compile time using static analysis.

Spring IoC container is the core of Spring Framework, since it creates the object, wire them together, configure and manage their complete life cycle from creation till destruction. It uses dependency injection to manage the components (called Spring Beans) that make up an application. 

From the provided configuration metadata, the container will get the instructions on what objects to instantiate, configure, and assemble. The configuration metadata can be represented either by XML, Java annotations, or Java code.

The Spring IoC container makes use of Java POJO classes and configuration metadata to produce a fully configured and executable system or application.
 
Spring provides two types of containers:
1). Spring BeanFactory Container: This is the simplest container providing the basic support for DI and is defined by the org.springframework.beans.factory.BeanFactory interface. The BeanFactory and related interfaces, such as BeanFactoryAware, InitializingBean, DisposableBean, are still present in Spring for the purpose of backward compatibility with a large number of third-party frameworks that integrate with Spring.

2). Spring ApplicationContext Container: This container adds more enterprise-specific functionality such as the ability to resolve textual messages from a properties file and the ability to publish application events to interested event listeners. This container is defined by the org.springframework.context.ApplicationContext interface.

What is difference between BeanFactory and ApplicationContext in Spring framework?
Both BeanFactory and ApplicationContext provides a way to get a bean from Spring IOC container by calling getBean("Bean_Name"). Here are a few differences between a BeanFactory and ApplicationContext:
1). BeanFactory uses lazy initialization approach whereas ApplicationContext uses eager initialization approach. i.e BeanFactory instantiate bean only when you call getBean() method while ApplicationContext instantiates Singleton bean when the container is started.
2).BeanFactory doesn't provide support for internationalization i.e. i18n but ApplicationContext provides support for it.
3). Annotation based dependency Injection is not supported by BeanFactory whereas ApplicationContext supports using annotation @PreDestroy, @Autowired.

Name a few implementations of ApplicationContext?
  • AnnotationConfigApplicationContext: For standalone java applications using annotations based configuration.
  • ClassPathXmlApplicationContext: For standalone java applications using XML based configuration.
  • FileSystemXmlApplicationContext: Similar to ClassPathXmlApplicationContext except that the xml configuration file can be loaded from anywhere in the file system.
  • AnnotationConfigWebApplicationContext and XmlWebApplicationContext for web applications.
What is the importance of Spring bean configuration file?
Spring Bean configuration is used to define all the beans that will be initialized by Spring Context. When we create the instance of Spring ApplicationContext, it reads the spring bean configuration file and initialize all the beans. Once the context is initialized, we can use it to get different bean instances.

Apart from Spring Bean configuration, this file also contains spring MVC interceptors, view resolvers and other elements to support annotations based configurations.

BeanFactory : It reads blue print of the file from the configuration files and return the instance of bean.

In the below example we will be using XmlBeanFactory.


1). create a Traingle class with draw() method.
public class Traingle {
    public void draw()
    {
        System.out.println("Drawing traingle..");
    }
}


2). In DrawingApplication, we will be creating the bean using BeanFactory.

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;

public class DrawingApplication {
    public static void main(String[] args) {   
        BeanFactory beanFactory=new XmlBeanFactory(new FileSystemResource("spring.xml"));
        Traingle traingle=(Traingle)beanFactory.getBean("traingle");
        traingle.draw();   
    }
}



When you execute DrawingApplication, it will call draw() method of Traingle.

3). create spring.xml in the root of the application.
 < ?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="traingle" class="com.spring.test.Traingle"/ >
 < /beans >  


PropertyInitilization with ApplicationContext : It is used to initialize the property of an object by specifying the value in the configuration XML.

1). Update the Traingle class, add the type.
public class Traingle {
    private String type;
   
    public void draw()
    {
        System.out.println("Drawing traingle..of type "+type);
    }
    //getters and setters of type   
}

2). In DrawingApplication, we will be using ApplicationContext to create the bean with the preset value of type.
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class DrawingApplication {
    public static void main(String[] args) {   
        ApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
        Traingle traingle=(Traingle)context.getBean("traingle");
        traingle.draw();   
    }
}

3). create spring.xml in the classpath.
 < ?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="traingle" class="com.spring.test.Traingle" >
     < property name="type" value="isosceles" / >
     < /bean >
 < /beans > 

Constructor Injection : Constructors are used to set the member variable values for Spring beans.

Injecting string-based values : Suppose in Traingle class we declare a constructor, which takes 'type' as an argument and in spring.xml, constructor-arg declared which invokes this constructor.

constructor-arg has a type attribute , if you don't specify the type attribute, by default string type constructor will be invoked.

1).
public class Traingle {
    private String type;
    private int height;
  
    public Traingle(int height)
    {
        this.height=height;
    }
    public Traingle(String type)
    {
        this.type=type;
    }
    public Traingle(String type, int height)
    {
        this.type=type;
        this.height=height;
    }
    public void draw()
    {
        System.out.println("Drawing traingle..of type "+type+", with height="+height);
    }
    //getters and setters of type and height
}

2).
 < bean id="traingle" class="com.spring.test.Traingle" >
     < constructor-arg value="isosceles"/ >
 < /bean >


3).
ApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
Traingle traingle=(Traingle)context.getBean("traingle");


This will initialize the bean by calling the constructor which takes String as an argument.

Injecting primitive values: The Traingle has another paramatrized constructor which takes the integer height. Suppose you want to draw a triangle by specifying the height, then you need to add 'type' element in constructor-arg. e.g

 < bean id="traingle" class="com.spring.test.Traingle" >
     < constructor-arg value="20" type="int"/ >
 < /bean >


Whenever you call context.getBean("traingle"), it will invoke the constructor which takes integer height as an argument.

Traingle class has one more constructor, which takes int height and String type as an argument. Suppose you want to invoke this constructor, then you need to make changes in spring.xml
 < bean id="traingle" class="com.spring.test.Traingle" >       
     < constructor-arg value="20" type="int"/ >
     < constructor-arg value="isosceles" type="String"/ >
 < /bean > 


Injecting Objects : We can use dependency injection to inject an object dependency to a Spring bean. We will create a Point class, which has two variables x and y. As the Triangle has three points, we will make changes in our Triangle class.

1). Point Class
package com.spring.test;

public class Point {
    private int x, y;
    @Override
    public String toString() {
        return "x="+x+", y="+y;
    }
    //getters and setters for x and y
       
}


2). add three Points in Traingle class.
package com.spring.test;

public class Traingle {

    private Point pointA, pointB, pointC;
    public void draw()
    {
        System.out.println("Drawing traingle..pointA:"+pointA+", pointB:"+pointB+", pointC:"+pointC);
    }
    //getters and setters of pointA, pointB, pointC
}


3). In the spring.xml, we will define three different beans for three points. Then in the triangle bean, we will give reference of these 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="traingle" class="com.spring.test.Traingle" >        
         < property name="pointA" ref="zeroPoint"/ >
         < property name="pointB" ref="point1"/ >
         < property name="pointC" ref="point2"/ >
     < /bean >
   
     < bean id="zeroPoint" class="com.spring.test.Point" >
         < property name="x" value="0"/ >
         < property name="y" value="0"/ >
     < /bean >
     < bean id="point1" class="com.spring.test.Point" >
         < property name="x" value="-20"/ >
         < property name="y" value="0"/ >
     < /bean >
     < bean id="point2" class="com.spring.test.Point" >
         < property name="x" value="0"/ >
         < property name="y" value="20"/ >
     < /bean >
 < /beans >


4).
ApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
Traingle traingle=(Traingle)context.getBean("traingle");
traingle.draw();


draw method will print:
Drawing traingle..pointA:x=0, y=0, pointB:x=-20, y=0, pointC:x=0, y=20


What are inner beans in Spring?
In Spring framework, whenever a bean is used for only one particular property, it’s advise to declare it as an inner bean. And the inner bean is supported both in setter injection ‘property‘ and constructor injection ‘constructor-arg‘.

Suppose in above example (Inserting Objects), point1 and point2 are only used for creating the triangle bean and are not used anywhere else. In such cases, we do not need to define bean definitions for point1 and point2 separately. Instead of this we will use inner bean.

In case of inner beans, 'id' is not required.

 < ?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="traingle" class="com.spring.test.Traingle" >
         < property name="pointA" ref="zeroPoint" / >
         < property name="pointB" >
             < bean class="com.spring.test.Point" >
                 < property name="x" value="-30" / >
                 < property name="y" value="0" / >
             < /bean >
         < /property >
         < property name="pointC" >
             < bean class="com.spring.test.Point" >
                 < property name="x" value="0" / >
                 < property name="y" value="20" / >
             < /bean >
         < /property >
     < /bean >

     < bean id="zeroPoint" class="com.spring.test.Point" >
         < property name="x" value="0" / >
         < property name="y" value="0" / >
     < /bean >
 < /beans >

Aliases :
We can give different names to the same bean by using Aliases. e.g:
 < alias name="traingle" alias="tgleAlias"/ >
This will create an Aliase for traingle bean. To get the traingle bean using Aliase:

Traingle traingle=(Traingle)context.getBean("tgleAlias");
Aliase can be given in the bean definition itself by using the 'name' property. e.g:

 < bean id="zeroPoint" class="com.spring.test.Point" name="zeroPointAlias" >
     < property name="x" value="0" / >
     < property name="y" value="0" / >
 < /bean >
   
idref:
The 'ref' attribute of the 'property' tag can point to 'id' or and 'aliase'. If you want to restrict it to ONLY id then idref can be used. e.g:

 < bean id="traingle" class="com.spring.test.Traingle" >
         < property name="pointA" idref="zeroPoint" / >
         < property name="pointB" >
             < bean class="com.spring.test.Point" >
                 < property name="x" value="-30" / >
                 < property name="y" value="0" / >
             < /bean >
         < /property >
         < property name="pointC" >
             < bean class="com.spring.test.Point" >
                 < property name="x" value="0" / >
                 < property name="y" value="20" / >
             < /bean >
         < /property >
     < /bean >
   
Since we have mentioned idref="zeroPoint", it will check if the bean with id =zeroPoint is available or not. If yes then it will refer to that bean, else through an exception.


How can you inject a Java Collection in Spring?Spring offers four types of collection configuration elements which are as follows:
  • list : This helps in wiring ie injecting a list of values, allowing duplicates.
  • set : This helps in wiring a set of values but without any duplicates.
  • map : This can be used to inject a collection of name-value pairs where name and value can be of any type.
  • props : This can be used to inject a collection of name-value pairs where the name and value are both Strings.
Example Of Initializing Collections : It is used if the member variable is a collection.
1). Traingle class is updated, now instead of PointA, pointB and pointC, it has a list of Points.
package com.spring.test;

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   
}


2). spring.xml need to be updated:
 < ?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="traingle" class="com.spring.test.Traingle" >
         < property name="points" >
             < list >
                 < ref bean="zeroPoint"/ >
                 < ref bean="point1"/ >
                 < ref bean="point2"/ >
             < /list >
         < /property >
     < /bean >    
     < bean id="zeroPoint" class="com.spring.test.Point" >
         < property name="x" value="0"/ >
         < property name="y" value="0"/ >
     < /bean >
     < bean id="point1" class="com.spring.test.Point" >
         < property name="x" value="-20"/ >
         < property name="y" value="0"/ >
     < /bean >
     < bean id="point2" class="com.spring.test.Point" >
         < property name="x" value="0"/ >
         < property name="y" value="20"/ >
     < /bean >
 < /beans > 


How to inject a java.util.Properties into a Spring Bean?
There are two ways to do it:
1). First way is to use  < props >  tag as below.
 < bean id="adminUser" class="com.scrutiny.common.UserEmails" >  
     < !-- java.util.Properties -- >
     < property name="emails" >
         < props >
             < prop key="admin" > khimaanshu@scrutiny.com < /prop >
             < prop key="support" > support@scrutiny.com < /prop >
         < /props >
     < /property >

 < /bean >
 2). You can use "util:" namespace as well to create properties bean from properties file, and use bean reference for setter injection.
 < util:properties id="emails" location="classpath:com/scrutiny/emails.properties" / > 


Bean Auto wiring : With this feature dependencies can be automatically wired, which in turn reduces the configuration that we need to do.

Suppose the Traingle class has pointA, pointB, pointC. If the name of beans in 'spring.xml' is same as member variables (in our case pointA, pointB, pointC), we can request Spring to use the auto wire feature by specifying autowire="byName".

 < ?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="traingle" class="com.spring.test.Traingle" autowire="byName"/ >    
     < 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 >


We can do the auto wire by type, this will work only if there is only 1 member variable in the bean and only 1 bean of each type. e.g only one Point member variable in Traingle and only one Point bean in spring.xml.

autowire by constructor does the constructor injection.

By default the autowire is off.

Explain different modes of bean autowiring?
  • no: This option is default for spring framework and it means that autowiring is OFF. You have to explicitly set the dependencies using tags in bean definitions.
  • byName: This option enables the dependency injection based on bean names. When autowiring a property in bean, property name is used for searching a matching bean definition in configuration file. If such bean is found, it is injected in property. If no such bean is found, a error is raised.
  • byType: This option enables the dependency injection based on bean types. When autowiring a property in bean, property’s class type is used for searching a matching bean definition in configuration file. If such bean is found, it is injected in property. If no such bean is found, a error is raised.
  • constructor: Autowiring by constructor is similar to byType, but applies to constructor arguments. In autowire enabled bean, it will look for class type of constructor arguments, and then do a autowire by type on all constructor arguments. Please note that if there isn’t exactly one bean of the constructor argument type in the container, a fatal error is raised.
  • autodetect: Autowiring by autodetect uses either of two modes i.e. constructor or byType modes. First it will try to look for valid constructor with arguments, If found the constructor mode is chosen. If there is no constructor defined in bean, or explicit default no-args constructor is present, the autowire byType mode is chosen.
How do you turn on annotation based autowiring?
To enable @Autowired, you have to register AutowiredAnnotationBeanPostProcessor, and you can do it in two ways.
1. Include  < context:annotation-config  >  in bean configuration file.
 < beans >
     < context:annotation-config / >
 < /beans >


2. Include AutowiredAnnotationBeanPostProcessor directly in bean configuration file.
 < beans >
     < bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/ >
 < /beans > 


How to get ServletContext and ServletConfig object in a Spring Bean?
There are two ways to get Container specific objects in the spring bean:
  • Implementing Spring *Aware interfaces, for these ServletContextAware and ServletConfigAware interfaces, for complete example of these aware interfaces, please read Spring Aware Interfaces
  • Using @Autowired annotation with bean variable of type ServletContext and ServletConfig. They will work only in servlet container specific environment only though. e.g:
@Autowired
ServletContext servletContext; 


ALSO READ: #Spring part 5 : More about @Autowired Annotation

Difference between FileSystemResource and ClassPathResource?
In FileSystemResource we need to give path of Spring Configuration file (spring.xml) relative to our project or the absolute location of the file.

In ClassPathResource spring looks for the file using ClassPath, so spring.xml should be included in classpath. If spring-config.xml is in “src” so we can give just its name because src is in classpath path by default.

We can say that, ClassPathResource looks in the class path and FileSystemResource looks in the file system.

-K Himaanshu Shuklaa..

1 comment:

Anonymous said...

amazing

just amazing

Post a Comment

RSSChomp Blog Directory