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?
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?
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?
Read More : #Spring part 2 : 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: The dependencies and the services required by beans are mentioned in configuration files. These are in an XML format. They comprise of many bean definitions and application-specific configuration options. They generally begin with a bean tag.
< bean name="myBean" class="com.khimaanshu.beans.MyTestBean" > < /bean >
2). Java-based configuration: The primary features in Spring Framework’s new Java-configuration support are @Bean annotated methods, and @Configuration annotated classes. 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 use annotations on the relevant class to describe the bean wiring into the component class itself. 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 the Bean life cycle in Spring Bean Factory Container?
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"). The BeanFactory is the most basic version of IOC containers, and the ApplicationContext extends the features of BeanFactory. Here are a few differences between a BeanFactory and ApplicationContext:
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‘.
Inner beans are always anonymous and they are always scoped as prototypes.
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:
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" / >
Define Bean Wiring.
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?
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:
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.
ALSO CHECK: Spring Interview Questions
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?
- Spring is a powerful open source, application framework created to reduce the complexity of enterprise application development.
- It is light-weighted and loosely coupled.
- Spring Framework uses POJOs, which makes application testing much easier.
- 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.
- Because of Spring Frameworks layered architecture, you can use what you need and leave which you don’t.
What are the various features of the Spring Framework?
- Lightweight: Spring Framework is lightweight when we talk about its transparency and size.
- Inversion of control: It is the principle where the control flow of a program is flipped. Here, the external sources like services, framework, and other components control the flow of a program instead of the programmer.
- Aspect-oriented Programming: Aspect-oriented programming in Spring supports binding development by splitting system services from application business logic.
- Container: The container is at the core of the Spring Framework. It is the container that creates the objects, binds them, configures them, and be in charge of their complete life cycle, which is from creation until the end.
- MVC Framework: The Spring Framework’s MVC web application framework is easy to use, and it is configurable. You can use other frameworks instead of picking the Spring MVC Framework.
- Transaction Management: Spring Framework uses a generic abstraction layer for transaction management. You can use Spring’s transaction support in container fewer environments.
- JDBC Exception Handling: You do not need to handle any database-related exceptions explicitly. Spring JDBC Framework handles it using the JDBC exception handling.
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.
In DI mainly three classes are involved:
- Client Class-This is the dependent on service class. In above example A is the Client class.
- Service Class-This provide service to client class. In above example B is the Service class.
- Injector Class-It is responsible for injecting Service class object into the client class.
In general, dependency injection can be done in three ways, namely : Constructor Injection, Setter Injection and Interface Injection. In Spring Framework, only constructor and setter injections are used.
Differentiate between constructor injection and setter injection.
- In Constructor Injection there is no partial injection and works better for many properties. There can be partial injection in case of Setter Injection and works better for few properties.
- Constructor Injection doesn’t override the setter property. However Setter Injection overrides the constructor property.
- Constructor Injection will create a new instance if any modification is done. Setter Injection does not create new instance if any modification is done.
- 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.
- Spring Beans are the objects that form the backbone of the user’s application.
- Beans are managed by the Spring IoC container. They are instantiated, configured, wired and managed by a Spring IoC container
- Beans are created with the configuration metadata that we supply to the container.
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.
Does Spring Bean provide thread safety?
The default scope of Spring bean is singleton, so there will be only one instance per context. That means that all the class level variables that any thread can update will lead to inconsistent data. Hence in default mode spring beans are not thread-safe.
However we can change spring bean scope to request, prototype or session to achieve thread-safety at the cost of performance. It’s a design decision and based on the project requirements.
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: The dependencies and the services required by beans are mentioned in configuration files. These are in an XML format. They comprise of many bean definitions and application-specific configuration options. They generally begin with a bean tag.
< bean name="myBean" class="com.khimaanshu.beans.MyTestBean" > < /bean >
2). Java-based configuration: The primary features in Spring Framework’s new Java-configuration support are @Bean annotated methods, and @Configuration annotated classes. 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 use annotations on the relevant class to describe the bean wiring into the component class itself. 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 the Bean life cycle in Spring Bean Factory Container?
- The Spring container instantiates the bean from the bean’s definition in the XML file.
- Spring populates all of the properties using the dependency injection, as specified in the bean definition.
- The factory calls setBeanName() by passing the bean’s ID, if the bean implements the BeanNameAware interface.
- The factory calls setBeanFactory() by passing an instance of itself, if the bean implements the BeanFactoryAware interface.
- preProcessBeforeInitialization() methods are called if there are any BeanPostProcessors associated with the bean.
- If an init-method is specified for the bean, then it will be called.
- Finally, postProcessAfterInitialization() methods will be called if there are any BeanPostProcessors associated with the bean.
- At the core of the Spring Framework, lies the Spring container.
- Inversion of Control (IoC) is the mechanism to achieve loose-coupling between Objects dependencies.
- Inversion of Control is the principle, where the control flow of a program is inverted, instead of the programmer controlling the flow of a program, the framework takes control of the program flow.
- 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.
- The container receives instructions for which objects to instantiate, configure, and assemble by reading the configuration metadata provided. This metadata can be provided 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.
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"). The BeanFactory is the most basic version of IOC containers, and the ApplicationContext extends the features of BeanFactory. Here are a few differences between a BeanFactory and ApplicationContext:
- BeanFactory is an interface defined in org.springframework.beans.factory.BeanFactory, where as ApplicationContext interface defined in org.springframework.context.ApplicationContext.
- BeanFactory uses lazy initialization approach whereas ApplicationContext uses eager initialization approach. i.e BeanFactory instantiate bean only when you call getBean() method while ApplicationContext loads all beans at startup. Thus, BeanFactory is lightweight as compared to ApplicationContext.
- The ApplicationContext supports almost all types of bean scopes, but the BeanFactory only supports two scopes — Singleton and Prototype. Therefore, it's always preferable to use ApplicationContext when building complex enterprise applications.
- BeanFactory doesn't provide support for internationalization i.e. i18n but ApplicationContext provides support for it.
- Annotation based dependency Injection is not supported by BeanFactory whereas ApplicationContext supports using annotation @PreDestroy, @Autowired.
- The ApplicationContext automatically registers BeanFactoryPostProcessor and BeanPostProcessor at startup. On the other hand, the BeanFactory does not register these interfaces automatically.
- 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 a Spring configuration file?
A Spring configuration file is an XML file, which mainly contains the classes information. It describes how those classes are configured as well as introduced to each other.
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‘.
Inner beans are always anonymous and they are always scoped as prototypes.
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;1). Traingle class is updated, now instead of PointA, pointB and pointC, it has a list of Points.
import java.util.List;
public class Traingle {
private List < Point > points;
public void draw()
{
System.out.println("Drawing traingle..");
points.forEach((point)- > System.out.println(point));
}
//getters and setter for points
}
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" / >
Define Bean Wiring.
- When beans are combined together within the Spring container, it’s called wiring or bean wiring.
- The Spring container needs to know what beans are needed and how the container should use dependency injection to tie the beans together, while wiring beans.
What is 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 to exclude a Bean from Autowiring?
1). We can exclude a bean from autowiring, by setting the autowire-candidate attribute to 'false'.
< bean autowire-candidate="false" id="mybeanone" class="com.test.scrutiny.MyBean"/ >
2). We can also disable/ turn off autowiring in this way:
@Bean
static FactoryBean < MyBean > myBean() {
return preventAutowire(new MyBean());
}
public static < T > FactoryBean < T > preventAutowire(T bean) {
return new FactoryBean < T > () {
public T getObject() throws Exception {
return bean;
}
public Class < ? > getObjectType() {
return bean.getClass();
}
public boolean isSingleton() {
return true;
}
};
}
3). Using Autowire.NO: We can turnoff the autowiring by using Autowire.NO, e.g:
@Bean(autowire = Autowire.NO, initMethod="init", destroyMethod="cleanup")
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
private MyBean getMyBean() {
return new MyBean ();
}
Does autowiring work for primitive datatypes?
No, Autowiring cannot be used to inject primitive such int, boolean, double, etc.. It works with reference only, alternatively we can use wrapper for the same. i.e. Integer, Boolean, Double, etc.
What are the limitations with auto wiring?
- Overriding possibility: You can always specify dependencies using
and settings which will override autowiring. - Primitive data type: Simple properties such as primitives, Strings and Classes can’t be autowired.
- Confusing nature: Always prefer using explicit wiring because autowiring is less precise.
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:
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.
ALSO CHECK: Spring Interview Questions
amazing
ReplyDeletejust amazing