Spring Framework
Spring Core
Spring has many parts. Core is about dependency injection /version where we have to decouple the classes.
Spring has containers just like a Tomcat has called a container. It manages the lifecycle of an object mentioned in XML similar to Tomcat.
This works based on Factory Pattern – A factory class can instantiate all the objects.
So if you ask for an Object to Spring Bean Factory – it will give you that particular object.
<xml >
<DocType ..
<bean id=” class=”” />
- XmlBeanFactory factory = new XmlBeanFactory (new ClassPathResource(“Beans.xml”));
2. BeanFactory factory = new ClassPathXmlApplicationContext(“spring.xml”);
Triangle triangle = (Triangle) factory.getBean(“triangle”);
Now if the triangle class was very complicated which required multiple other classes the bean def would change accordingly. The advantage is that you can get the Triangle class with just one statement instead of defining several of its dependencies every time the class is instantiated at multiple places.
You can also use ApplicationContext instead of BeanFactory
The ApplicationContext interface is built on top of the BeanFactory interface. It adds some extra functionality such as simple integration with Spring’s AOP, message resource handling (for I18N), event propagation, application layer specific context (e.g. WebApplicationContext) for web application, annotation based dependency .
BeanFactory uses lazy initialization but ApplicationContext uses eager initialization.
However, to lazy load a bean via ApplicationContext once can use lazy-init=”true” in bean definition.
Note : only singletons have the concept of lazy and eager loading, prototype are always made on request basis so they are loaded on request (lazily only).
For Java class based configuration
ApplicationContext ctx = new AnnotationConfigApplicationContext(HelloWorldConfig.class);
HelloWorldConfig class willl @Configuration over it
@Import(HelloWorldConfig2.class)
HelloWorldConfig2 configuration class is imported into HelloWorldConfig
The above two methods are for setter injection. <property name=”” value=””>
Constructor based injection
We can inject using constructor for the class.
<bean..>
<constructor-arg value”” type=”” index=””>
</bean>
Type and index r optional
Type defines type of class of argument – java.lang.String – to be used to explicitly say that this argument is of type String
Index – position of argument – to be used if multiple String args etc are there
Refer objects in a class/ Injection Objects
If a class has member variables as objects – they will be defined in spring.xml and can be used as
<bean …>
<property name=”” ref=”<ref bean id here>” /> (instead of value we use ref to refer another bean)
</bean>
Idref vs ref
<bean class=”A” id=”a” />
<bean class=”B”/>
<constructor-arg>
<ref bean=”a”/>
<idref bean=”a”/>
</constructor-arg>
</bean>
public B(A a, String string) {
string.equals(“a”); //true
}
So with ref you can reference an object and with idref you just reference the name of the bean
For idref one could have used direct string property
<constructor-arg type = “java.lang.String” value = “Zara”/>
But if you use idref it ensures at deployment time that bean with that name exists otherwise it will throw error.
InnerBean
<bean …>
<property name=”” >
<bean class = “” ></bean>
</property>
</bean>
Alias
<alias name “<bean id>” alias””/>
Initializing collection Objects
For string values
<property name = “addressList”>
<list> -> could also be <set> / <map>
<value>INDIA</value>
<value>Pakistan</value>
<value>USA</value>
<value>USA</value>
</list>
</property>
For map
<map>
<entry key = “1” value = “INDIA”/>
</map>
For objects
<bean>
<property name=”” >
<list>
<ref bean =””>
<ref bean =””>
</list>
</property>
</bean>
Injecting null values
<property name = “email”><null/></property>
Types of bean scope
- Singleton – one object of a bean per spring container
- Prototype – multiple objects of bean per spring container – default
- Global – one object per HTTP application. [MVC]
- Session – one object per HTTP session. [MVC]
- Request – one object per HTTP Request[MVC]
<bean id=”” type =”” scope=””>
Interfaces which class can implement to get information
ApplicationContextAware
MYclass implements ApplicationContextAware
@overrider
Void setContext… (AC content ) {
this.context = context;
}
This way you can fetch the context in the class, similar interfaces exist like BeanNameAware etc.
Note that in newer versions it may be better to use annotations, rather than implementing spring-specific interfaces. Now you can simply use:
@Inject // or @Autowired
private ApplicationContext ctx;
Bean Definition Inheritance
Just like inheritance there is parent child relationship in bean definitions too.
Two beans can be defined by that relationship. The child can override the properties of the parent if it defines the same properties again.
<bean id =type= abstract= parent=
One could define a bean abstract or child of some bean using parent.
Bean Definition Template
You can create a Bean definition template, which can be used by other child bean definitions without putting much effort.
<bean id = “beanTeamplate” abstract = “true”>
Lifecycle Methods
Called before initialization and destruction
Can be called in Two ways for each bean
- Implementing Initializingbean, DisposableBean / BeanPostProcessor
- Using xml to define init-method, destroy-method in bean definition
<bean id = “helloWorld” class = “com.gaurav.HelloWorld”
init-method = “init” destroy-method = “destroy”>
On a global level – <beans > every bean will be searched for the default-init-method, default-destroy-method
In any of the methods above each bean will have a seperate method for initialization and destruction.
Common method for Initialization for all beans can be given in the following manner.
- Implement BeanPostProcessor
- register it in spring.xml
The same method will execute for all beans
Property Substitution
If you want to assign a value of a bean through properties file then it can be done by
- Register PropertyPlacementHolderConfig in spring.xml
- Inside it a property will have value as the location/name of the properties file
3.
<bean class=”org.springframework.beans.factory.config.PropertyPlaceholderConfigurer”
>
<property name=”” value = “${property1.propertyA}”>
// or give an entire properties file
<property name=”location”>
<value>database.properties</value>
</property>
The property file can be Used like this
<property name=”driverClassName” value=”${jdbc.driverClassName}” />
To use the value in a bean file
@Value( “${jdbc.url}” ) private String jdbcUrl;
@Required – if a function need to be called at the time of initiation then it has to be annotated accordingly so that if it setter the attribute which will be accessed should not give NullPointerException
@Required
Void setValue( String a)
The error will be thrown at applications start up.
You need to add a postprocessor in spring.xml to use annotation.
Also in case of optional dependency injection this can be used.
public class FooService {
@Autowired(required = false)
private FooDAO dataAccessor;
}
Else it can throw nosuchbeanfoundexception
Autowiring
If you want bean injected automatically. Not constructor injection.
Types
Name – ids of all beans should be same as member variables
Type – if there r member variables of different types. No two member variables should be of same type.
@Autowired -. It will search for the type of this class in spring container , if it finds multiple entries then it searches for name match. If it doesn’t find then it fails.
Solving UnsatisfiedDependencyException with Spring autowiring
To overcome this problem there are two options –
- primary candidate – Identify a primary candidate for auto wiring bean and set that as primary=”true”
- <bean id=”payment” class=”org.netjs.springexp.prog.CashPayment” primary=”true”/>
- Exclude a bean from autowiring – You can exclude a bean from being autowired. For that set the autowire-candidate attribute of <bean> tag to false.
- <bean id=”creditPayment” class=”org.netjs.springexp.prog.CreditPayment” autowire-candidate=”false” />
@Autowired over a constructor
If there are more than one constructor in the class, only one constructor can have @Autowired annotation. This constructor should not be public.
@Autowired with Field
The class field can also be autowired using @Autowired annotation. Any number of fields can be autowired within a class. The fields which are autowired should not be public
@Qualifier(“qualifier”) – this is used with @Autowired to specify which bean to autowire.
The same qualifier needs to given in bean definition in spring.xml
@Autowired
@Qualifier(“student1”)
private Student student;
JSR 250 Annotations
@Resource – to inject based on the name same as @Autowired + @Qualifier used over functions.
If you don’t want to use two annotations (the @Autowired and @Qualifier) you can use @Resource to combine these two.
@Inject = @Autowired (@Inject is JSR specification, @Autowired is spring specific)
<bean id=”a” class=”org.sssit.A” autowire=”constructor”></bean>
IF class has multiple constructors then by default the constructor with highest number of parameters is injected.
<bean id=”a” class=”org.sssit.A” autowire=”byName”></bean>
If the properties of A name is not found – throws Exception
<bean id=”a” class=”org.sssit.A” autowire=”byType”></bean>
IF multiple beans of same type found again throws Exception
<bean id=”a” class=”org.sssit.A” autowire=”no”></bean>
@PostConstruct @PreDestroy – same as init and destroy methods.
You need to add a post processor in spring.xml to use this annotation.
One simple way to avoid all annotation related post processors is using
<context:annotation-config/>
@component – marks a class as a bean, it will auto instantiated with no mapping in spring.xml
It will have name same as class with a small letter.
<context:component-scan: base-package=””/> – scans these package to find @component, @Repository, @Controller annotations
Message Source – Resource bundle
Register a bean for the class ResourceBundleMessageSource along with resource bundles as a list
<bean id=”messageSource” class=”org.springframework.context.support.ResourceBundleMessageSource”>
<property name=”basename”>
<value>locale\customer\messages</value>
</property>
</bean>
The MessageSource object can be wired into any class to take this bean.
messageSource.getMessage(<property name>, <args to message>, <default message>, <locale> );
Listeners
You can implement listeners which listen events
Implementing ApplicationListener make a listener – which listens
A class which has to be publish an event has to implement ApplicationEventPublishAware
This class needs to have a setter for the publisher which the Spring will set from the application context.
This publisher can publish the event.
context:component-scan
Scans for all these annotations
- @Component
- @Repository
- @Service
- @Controller
One advantage of this element is that it also resolves @Autowired and @Qualifier annotations. Therefore if you declare <context:component-scan>, is not necessary anymore declare <context:annotation-config> too.
Context:annotation-config – scans for Annotations only in already defined beans in XML file.
mvc:annotation-config
used for enabling the Spring MVC components with its default configurations.
- Support for formatting Number fields with @NumberFormat
- Support for formatting Date, Calendar, and Joda Time fields with @DateTimeFormat, if Joda Time is on the classpath
- Support for validating @Controller inputs with @Valid, if a JSR-303 Provider is on the classpath
- Support for reading and writing XML, if JAXB is on the classpath
- Support for reading and writing JSON, if Jackson is on the classpath
context:annotation-driven
it will resolve @Autowired and @Qualifier annotations for the beans which are already created and stored in the spring container.
context:component-scan can also do the same job, but context:component-scan will also scan the packages for registering the beans to application context. context:annotation-config will not search for the beans registration, this will only activate the already registered beans in the context.
Spring AOP
Why AOP?
In object oriented programming there are many cross cutting concerns which are not specific to an object. These are required globally by the application
Like logging
Security
Transactions
If they are used in OOP then there are some problems
- Too many relationships with these classes. – Classes are tightly coupled.
- Code is required in all classes
- Need to change code of every class using these common classes in case there is change.
How AOP Helps?
- It is a common unit – provides configurable options where to call these common functions for each class.
- There is low coupling
- Code need not be changed in every class – just configuration.
Just like Triggers in SQL, Filters in Servlets.
Installation
Aspecjrtr.jar
Aspectjrtweaver.jar
Cglib.jar – used for generating classes by Spring. Spring modifies the original java source to add the Aspects at appropriate points and then generates a class. This library can add classes to a java program after the compilation phase as JAVA programs are linked during the runtime phase so this works.
Asm.jar – cglib is built over it.
Implementation
- A class which defines cross cutting concerns must be labelled as @Aspect
- The functions of this class are called Advice. These can be called before/after execution of any method in the spring container.
- @Before execution ( public String getName() ) annotation over the Advice
@Before execution ( public String getName() ) – runs before every getName() of every class.
How to restrict it to a particular class – @Before execution ( public String org.gaurav.Messenger.getName() )
Pointcuts – are the points where advice are supposed to run like before getName().
WildCards – help us to define PointCuts
Advice gets executed only for user defined method execution. It has nothing to do with Springs initialization of Objects. Otherwise you could interfere with the framework.
for all functions beginning with get –
@Before(“execution ( public String get* )”)
for all functions beginning with get and all return types –
@Before(“execution ( public * get* )”)
for all functions beginning with get, all return types & all scopes –
@Before(“ execution ( * get* )”) – you could also use @Before execution (* * get* )
for all functions beginning with get, all return types, all scopes & multiple arguments or if the function takes arguments
@Before execution ( * get* (*) )
for all functions beginning with get, all return types, all scopes & multiple arguments or no arguments
@Before execution ( * get* (..) )
for all functions beginning with get, all return types, all scopes & no arguments
@Before execution ( * get* () )
For all functions of a class
@Before execution (* * org.gaurav.Messenger.*(..) )
Or
@PointCut (within ( org.gaurav.Messenger )
For all functions of a package
@PointCut (within ( org.gaurav.Messenger. )
For all functions of a package & sub packages
@PointCut (within ( org.gaurav.Messenger.. )
For all functions that have String args
@Before( “args(String)”)
Apply multiple advices to various points?
We can use same annotation before two functions but spring gives a better way to manage
@Before ( f3() )
Public void f1(){ some lines here }
@Before ( f3() )
Public void f2(){ some lines here }
@PointCut ( { EXP} )
Public void f3(){ let this be empty }
You can chain the pointcuts with conditions
@Before ( EXP1 && EXP2 )
Both functions are dependent on the expression in f3() even if it is empty.
*EXP could also be f1() too
How to get a function name for which the advice is executing on?
EXP
Public void f1( JointCut jc )
{
jc.toString() – returns name of object.
jc.getTarget() – returns object on which it is executing.
}
You can use joint cuts to restrict on how the advice should behave for a particular method.
Types
- @Before
- @After
- @AfterReturning
- @Around – acts as both before and after
- @AfterThrowing
Fetch function param in the advice
@Before(“args(name)”)
Public void f1( String name ) – f1 is advice . The exp tells AOP that it is argument of type String as it is mentioned in the signature – which is passed to the function.
Execute and Fetch function param in the advice whose return type is String
@AfterReturning(pointcut =“args(name)”, returning=”returnString”)
Public void f1( String name, String returnString )
Execute and Fetch function param in the advice whose return type is anything
@AfterReturning(pointcut =“args(name)”, returning=”returnString”)
Public void f1( String name, Object returnString )
Similarly one can define what advice to run on what exception. @
@Around
Void f(PRoceedingJointCut p) {
Code before
p.proceed();
Code after
}
Custom Annotations
- Define an interface
- In the spring.xml
@Before “@annotation(org.gaurav.mypackage.LoggerCustom)” )
Void advice (){}
3. Using it
@LoggerCustom
Void f1 ()
All these annotations can be turned to XML binding as well
Spring AOP works on the concept of Proxy objects
Class abc {
Public String f1 {
return “HI”;
}
}
Class abcProvider extends abc {}
Public String f1 {
Run before advice() – injects code based on annotation we provided to AOP
return “HI”;
Run before advice() – injects code based on annotation we provided to AOP
}
}
Spring Data
Spring allows connecting to several databases. Just like JDBC, it also has certain classes that can help to make work easier.
To make a JDBC with Spring class
One can use the same concepts except that Spring can inject the Data Source at run time from the one defined in configuration.
To further the maintainability and availability
One can use JDBCTemplate.
JDBCTemplatejust needs a DataSource object as a parameter. It takes care of the rest like opening the connection, closing the connection, executing the query etc.
The data source object created in “JDBC with Spring class” can be used and so only a query needs to be set. This does the work of executing the query.
DataSource Is class of type org.springframework.jdbc.datasource.DriverManagerDataSource
To execute Query
We use function jdbcTemplate.query(…..) ,jdbcTemplate.queryForInt(…..), jdbcTemplate.queryForObject(…..)
The params are like Query String, PArameters, RowMapper
RowMapper is an interface which needs to be implemented in a class.
It maps Resultset to a row/ user defined object.
Like if you are obtaining Student objects in ResultSet (which doesn’t understand the info it is carrying)
You can easily map the ResultSet data of each row into one object of Student.
There are various jdbcTemplate classes
- jdbcTemplate – for question mark parameters
- NamedParameterJdbTemplate – to be used for named parameters.
- SimpleJdbcTemplate – Can be used for both the named and question mark parameter
A good way to directly use the jdbc template without having to provide many lines of code in the class is to
Extends JdbcDaoSupport / SimpleJdbcDaoSupport /..
These classes have no functions to extend but a member variable “DataSource” which needs to be initialized.
The class extending this needs to be provide a data source in bean and then you get the jdbc template prepared object using a getter
this.getJdbcTemplate()
Integrate with Hibernate
One can import the hibernate libraries and import them to integrate the Hibernate with Spring.
Define a SessionFactory bean with required properties – dataSource, packagesToScan(for any data models) , define hibernate properties (dialect etc).
One does not need a seperate Hibernate.cfg here because spring.xml can be used for the same purpose.
Once SessionFactory which is a heavy object is constructed – this needs to be done only once – it will be called in any transaction to Open session and execute the query.