Spring framework is based on 'Inversion Of Control (IoC)' principle, also know as 'Dependency Injection (DI)' principle.
In this principle objects define their dependencies in configuration metadata. The IOC container looks up the configuration metadata and injects the dependencies when it creates object instance.
Since this process is inverse of objects creating instances of their dependencies, this principle is known as the 'Inversion Of Control (IOC) principle'. Since dependent object instances are injected into the object instance, this principle is also know a 'Dependency Injection (DI) principle.'
Spring framework implements an 'Inversion Of Control (IoC)' container, known as Spring IoC container, which manages the life-cycle of objects, known as Beans, in an application. The Spring IoC container is responsible for instantiating, configuring and assembling the beans in an application.'
Beans, and the dependencies among them, are maintained via configuration metadata by the application developer. The configuration metadata can be represented in XML or Java annotations. The Spring IoC container looks up the configuration metadata, instantiates dependent beans, and injects them into the bean that it is instantiating.
Spring framework provides the 'org.springframework.context' and 'org.springframework.beans' packages that represents the Spring IoC container.
BeanFactory - 'org.springframework.context.BeanFactory' provides the configuration framework and functionality.
ApplicationContext - 'org.springframework.context.ApplicationContext' interface which extends from BeanFactory interface provides more enterprise specific functionality.
WebApplicationContext - In addition Spring framework also provides application-layer specific contexts such as WebApplicationContext that can be used in web applications.
ApplicationContext Implementations - Spring framework provides several implementations of the ApplicationContext interface. For XML based configuration metadata, the commonly used implementations are ClassPathXmlApplicationContext and FileSystemXmlApplicationContext.
In Spring framework you can maintain configuration metadata in following formats.
XML-based configuration - Configuration metadata is traditionally maintained in XML format.
Annotation-based configuration - From Spring version 2.5, you can maintain configuration metadata using annotations.
Java-based configuration - From Spring version 3.0 onwards, you can use Java annotations, provided by Spring JavaConfig project. This is the most commonly used format now.
Following are some of the properties that are defined in the configuration metadata of a bean.
id - Specifies a unique identifier for the bean.
Class - Specifies the type of the class that has to be instantiated.
Name - Specifies one or more aliases for the bean that it can be referred to by.
Scope - Specifies the scope of the bean instance - singleton, prototype, request, session, application, or websocket.
Constructor args - Specifies the arguments that the Spring IOC container uses for constructor-based dependency injection.
Properties - Specifies the arguments that the Spring IoC container uses for setter-based dependency injection.
Autowiring mode - Specifies the autowire mode - no, byName, byType, or constructor.
lazy-init - Specifies if the bean instance has to be created when it is first requested, rather than at startup.
In XML-based configuration you use the elements <beans/> and <bean/> to configure beans whose lifecycle will be handled by Spring IoC container.
In Java-based configuration the annotations @configuration and @bean are used to configure beans whose lifecycle will be handled by Spring IoC container.
@configuration is a class level annotation and plays the same role as <beans/&t; element. It indicates that the primary purpose of the class is that it is a source of bean configurations.
@Bean is a method level annotation which indicates that the method instantiates and returns a bean that will be managed by the Spring IoC container.
//XML-based bean configuration
<beans>
<bean id='bean1' class='com.interviewgrid.Bean1'>...</bean>
<bean id='bean2' class='com.interviewgrid.Bean2'>...</bean>
</beans>
//Java-based bean configuration
@Configuration
public class MyConfiguration {
@Bean
public MyBean1 myBean1() {
return new MyBean1();
}
@Bean
public MyBean2 myBean2() {
return new MyBean2();
}
}
Following are the three different ways of instantiating beans.
Instantiation with a constructor - Spring framework can instantiate and manage any Java class. With XML-based configuration you can specify the bean class as follows.
<bean id='myBean' class='com.interviewgrid.MyBean'/>
Instantiation with a static factory Method - Spring framework can instantiate and manage any class defined to be instantiated with a static factory method. With XML-based configuration you can specify the bean class as follows.
<bean id='myBean' class='com.interviewgrid.MyBean' factory-method='getInstance'/>
Instantiation with an instance factory - Spring framework can instantiate and manage any class defined to be instantiated with an instance factory method. With XML-based configuration you can specify the bean class as follows.
<bean id='myBean' factory-bean='com.interviewgrid.MyBean' factory-method='getInstance'/>
//Instantiation with a constructor
<bean id='myBean' class='com.interviewgrid.MyBean'/>
//Instantiation with a static factory method
<bean id='myBean' class='com.interviewgrid.MyBean' factory-method='getInstance'/>
//Instantiation with an instance factory method
<bean id='myBean' class='com.interviewgrid.MyBean' factory-method='getInstance'/>
Spring framework supports two variants of dependency injection. Constructor-based dependency injection and Setter-based dependency injection.
Constructor-based Dependency Injection - In constructor based dependency injection, the Spring IOC container invokes the constructor of the class that it is instantiating, and injects the arguments to the constructor.
With XML-based configuration you can specify the constructor args using the <constructor-arg> element.
Setter-based Dependency Injection - In setter based dependency, the Spring IOC container instantiates the class using constructor, and then calls the setter methods of the class to inject the dependencies.
With XML-based configuration you can specify the constructor args using the <property> element.
//Constructor-based dependency injection
<beans>
<bean id='myBean1' class='com.interviewgrid.MyBean1'>
<constructor-arg ref='myBean2'/>
</bean>
<bean id='myBean2' class='com.interviewgrid.MyBean2'/>
</beans>
//Setter based dependency injection
<beans>
<bean id='myBean1' class='com.interviewgrid.MyBean1'>
<property name='myBean2' ref='myBean2'/>
</bean>
<bean id='myBean2' class='com.interviewgrid.MyBean2'/>
</beans>
You can use the elements ,
<bean id='myBean' class='com.interviewgrid.MyBean'>
//properties - results in a setMyEmails(java.util.Properties) call
<property name='myEmails'>
<props>
<prop key='administrator'>[email protected]</prop>
<propkey='support'>[email protected]</prop>
<prop key='development'>[email protected]</prop>
</props>
</property>
//list - results in a setMyList(java.util.List) call
<property name='myList'>
<list>
<value>value1</value>
<value>value2</value>
</list>
</property>
//map - results in a setMyMap(java.util.Map) call
<property name='myMap'>
<map>
<entry key='key1' value='value1'/>
<entry key='key2' value='value2'/>
</map>
</property>
//set - results in a setMySet(java.util.set) call
<property name='someSet'>
<set>
<value>value1</value>
<value>value2</value>
</set>
</property>
</bean>
By default the Sprint IOC container, or the ApplicationContext, eagerly instantiates all singleton beans as part of the initialization process.
You can configure a singleton bean such that the Spring IOC container does not instantiate this bean as part of the initialization process. This is known as lazy-initialization of the bean.
In XML-based configuration this property is controlled by using the lazy-init attribute on the <bean/> element.
<bean id='myLazyBean' class='com.interviewgrid.MyLazyBean' lazy-init='true'/>
Spring framework supports six bean scopes. Four of the six scopes are available only for web-aware application context.
Singleton - Singleton scope is the default scope for beans. In singleton scope a single bean instance is created for a single bean definition for each Spring IoC container.
Prototype - In prototype scope multiple bean instances are created for a single bean definition. Every request to a prototype bean results in the creation of a new bean instance.
Request - In Request scope a different bean instance is created for each HTTP request.
Session - In Session scope a different bean instance is created for each HTTP session.
Application - In Application scope a different bean instance is created for each HTTP ServletContext.
WebSocket - In WebSocket scope a different bean instance is created for each WebSocket.
In XML-based configuration the scope of a bean is specified by the scope attribute on the <bean/> element.
In Java-based configuration the scope of a bean is specified by the @scope annotation defined on the method that instantiates and returns the bean.
//XML_based bean configuration
//Prototype scoped bean
<bean id='MyPrototypeBean' class='com.interviewgrid.MyPrototypeBean' scope='prototype'/>
//Java-based bean configuration
@Configuration
public class MyConfiguration {
@Bean
@scope('prototype')
public MyPrototypeBean myProtoTypeBean() {
return new MyPrototypeBean();
}
}
You can dependency-inject a prototype scoped bean to a singleton scoped bean. However, a single instance of the prototype scoped bean is created and injected into the singleton scoped bean at initialization time. So at runtime a singleton scoped bean has a reference to the same instance of prototype scoped bean.
If you require a different instance of the prototype scoped bean for each method invocation on the singleton bean then you can use method injection.
You can dependency inject a shorter-lived scoped bean (example - session scoped bean) into a longer-lived scoped bean (example - singleton) by using a proxy for the shorter-lived scoped bean.
As part of the initialization process, the IoC container creates a proxy object for the shorter-lived scoped bean and injects it into the singleton bean.
When a method is invoked on the proxy object, the proxy fetches the real object (in this example from session) and invokes the method on that object.
In XML_based configuration the proxy is configured using the element '<aop:scoped-proxy/>'
In java-based configuration the @scope annotation provides similar support.
//XML_based configuration - session scoped bean
<bean id='MySessionBean' class='com.interviewgrid.MySessionBean' scope='session'
<aop:scoped-proxy/>
</bean>
//java-based configuration - session scoped bean
@Bean
@SessionScope
public MySessionBean mySessionBean() {
return new MySessionBean();
}
You can load the configuration definitions from one configuration class into another configuration class using the @import annotation.
@Configuration
public Class MyConfigA { ... }
@Configuration
@import('MyConfigA')
public class MyConfigB { ... }
Spring Data framework has an in-built query builder mechanism that derives queries based on the method name.
Method names are defines as 'find...By..','count...By...' etc. 'By' acts as the delimiter to identify the start of the criteria. 'And' and 'Or' are used to define multiple criteria. 'OrderBy' is used to identify the order by criteria.
findByFirstname(String firstName);
findByFirstnameAndLastname(String firstName, String lastName);
findByFirstnameAndLastnameOrderByFirstnameAcs(String firstName, string lastName);
Spring framework provides the following interfaces and classes to support data validations.
Validator - Interface that defines methods to validate data objects.
Errors - Interface that defines methods to store and expose validation errors on a data object.
BindingResult - Interface that extends from Errors and represents binding results.
ValidationUtils - Utility class providing convenient methods for invoking a validator and for rejecting empty fields.
You can implement a custom validator by implementing the Validator
interface and implementing the methods supports()
and validate()
.
Supports(Class c) method takes an argument of type Class which defines the type of object that this validator will validate.
validate(Object o, Errors e) method takes in two arguments -
1. An argument of type Object that this validator will validate
2. An argument of type Errors which will store and expose the validation errors.
Aspect Oriented Programming is a programming methodology which aims to increase the modularity of the program by enabling separation of cross-cutting concerns.
Cross-cutting concerns refers to features or functions that apply across multiple functional areas.
Examples of cross-cutting concerns are logging and transaction management which cut across multiple types and objects.
Aspects, Joins points, Advices, and Pointcuts are the core components of AOP.
Aspect - Aspect is a module that represents a cross-cutting concern.
Join point - Join point is a specific point in a running program, such as execution of a method or handling of an exception.
Advice - Advice specifies when the aspect acts at a particular join point - before, after, or around
Pointcut - Pointcut is an expression and a way to specify or match join points.
Aspect Oriented Programming is one of the key components of Spring framework (Spring AOP).
Spring AOP is not a comprehensive framework such as AspectJ, rather it aims to solve common enterprise application problems by providing a simple integration between AOP implementation and Spring IoC.
Spring AOP provides the ability to develop custom aspects by either using XML-based approach or @AspectJ annotation approach, both of which utilize the AspectJ pointcut language.
Spring AOP provides the following types of Advices.
Before advice - Advice that runs before a join point
After returning advice - Advice that runs if a join point completes normally without any exceptions
After throwing advice - Advice that runs if a join point exits with an exception.
After advice - Advice that runs irrespective of how the join point exits - normally or with exception.
Around advice - Advice that can run before and after join point.
Aspects in Spring AOP are regular Spring beans. Any Spring bean can be declared as an Aspect by decorating the bean either by XML-based configuration or by by AspectJ annotation.
In XML-based approach you can declare a bean as an aspect by using the element <aop:aspect>
In annotation based approach you can declare a bean as an aspect by using the AspectJ annotation @Aspect
//XML-based configuration
<aop:aspect id='myAspect' ref='myBean'>...</aop:aspect>
//Annotation based configuration
@Aspect
public class myBean {...}
In XML-based approach you can declare a Pointcut by using the element <aop:pointcut>
along with the pointcut expression.
In annotation based approacha you can declare a Pointcut by using the AspectJ annotation @Pointcut
//XML-based configuration
<aop:pointcut id='...' expression='...'>...</aop:pointcut>
//Annotation based configuration
@Pointcut('...')
public void myMethod() {...}
Spring AOP provides five kinds of advices - before, after returning, after throwing, after, and around.
In XML-based approach you can declare these advices by using the elements <aop:before>
, <aop:after-returning>
, <aop:after-throwing>
, <aop:after>
, and <aop:around>
.
In annotation based approach you can declare these advices by using the AspectJ annotations @Before
, @AfterReturning
, @AfterThrowing
, @After
, and @Around
Spring framework provides transaction management support having the following benefits and capabilities.
Consistent programming model that can be used across different transaction APIs - JTA, JPA, JDBC, Hibernate, etc.
Supports declarative and programmatic transaction management
Seamlessly integrates with Springs data access abstractions.
You can make methods of a class to be transactional by applying the @Transactional
annotation.
If you want all methods in the class to be transactional you can apply the annotation to the class.
If you want only some methods to be transactional you apply the annotation to each of the methods that are transactional.
In addition to annotating the class and methods, you have to annotate a configuration class (a class annotated with @Configuration
annotation) with @EnableTransactionManagement
annotation.
Spring framework provides convenient annotations that can be used for the implementation of the DAO.
Spring framework provides the @Repository
annotation that can be applied to the DAO class. This annotation provides exception translation features, and configuration with out traditional XML entities for the DAOs.
Depending on the persistence technology used the persistence resources (example - JdbcTemplate
and DataSource
for JDBC, EntityManager
for JPA, SessionFactory
for Hibernate) can be dependency injected into the DAO.