First SPRING
First SPRING
Spring is based on beans. Every thing in Spring is designed as beans. This is basically used in business layer.
4. update web.xml file to configure spring as web container. Web.xml file will look like as under:
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-
app_2_4.xsd">
<display-name>
SpringFramework
</display-name>
<welcome-file-list>
<welcome-file>/WEB-INF/jsp/common/Index.jsp</welcome-file>
</welcome-file-list>
<servlet> <servlet-name>springschool</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet><servlet-mapping>
<servlet-name>springschool</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
1
</web-app>
Servlet-name is important. If you has given servlet name as “springschool” then spring framework will search for ‘springschool-
servlet.xml’ file for spring configuration.
}
Address Bean is:
public class Address {
private String state;
private String country;
private String city;
private String VPO;
private String street;
private String houseNumber;
//getter setter for these properties and toString method.
}
Student Bean is:
public class StudentBean {
private String id;
private Name name;
private Address address;
//getter setter for these properties and toString method.
}
After creating and controller folder structure will look like as below:
2
6. Next step is to write springschool-servlet.xml file which will configure the entire beans for spring. This file look like as below:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
3
p:lastName="Mehta"
/>
7. Next step is to write jsp files. We will write two JSP files: Index.jsp and Error.jsp.
4
5
Wiring Beans:
1. Spring has extensive set of method to wire a bean with corresponding xml.
2. Bean Factory can be created using two ways. One way is to create through BeanFactory interface and another one is through
ApplicationContext.
6
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getMiddleName() {
return middleName;
}
public void setMiddleName(String middleName) {
this.middleName = middleName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getInitial() {
return initial;
}
public void setInitial(String initial) {
this.initial = initial;
}
public String toString() {
String sBuff = new String();
sBuff=this.initial;
sBuff=sBuff+" "+this.firstName;
sBuff=sBuff+" "+this.middleName;
sBuff=sBuff+" "+this.lastName;
return sBuff;
}
}
<constructor-arg index="0">
<value>CONMehta</value>
</constructor-arg>
7
</bean>
For this we also need to change our bean class. We need to add following code snippet.
Name(String first,String last)
{
firstName=first;
lastName=last;
}
Index attribute in constructor tag specify the index of the argument in constructor method.
8
<bean name="student" class="com.GHS.student.beans.StudentBean"
p:id="testID"
init-method="start"
destroy-method="end" scope="prototype">
<property name="name">
<ref bean="name"/>
</property>
<property name="address">
<ref bean="address"/>
</property>
</bean>
Init-method: Corresponding method will be called before initialization start or we can say before bean given to application for use.
Prototype value defines that every time a new bean will be generated whenever application request for this.
Singleton value defines that only one instance will be created for this bean and reference to this bean will be generated whenever
application request for this.
6. We can configure new bean inside existing one. However we can not reuse inner bean anymore.
<bean id="courseService" class= "training.CourseServiceImpl" >
<property name="studentService">
<bean
class="training.StudentServiceImpl"/>
</property>
</bean>
<property name="list">
9
<list>
<ref bean="name"/>
</list>
<list>
<ref bean="address"/>
</list>
</property>
As we can see two default parameters given in the list. Whenever application request for studentBean class this list will be
initialized with name and address object. So list will never be null.
Set:
Set wiring is very similar to List.
Suppose we have bean class like:
public class StudentBean {
As we can see two default parameters given in the list. Whenever application request for studentBean class this list will be
initialized with name and address object. So list will never be null.
Map:
Map wiring is very similar to map in java. However there is one limitation that key value can only be a string.
Suppose we have bean class like:
public class StudentBean {
10
Props:
Props wiring is very similar to map. However big difference is that both key and value can only be string. So no need to write value
tag.
Suppose we have bean class like:
public class StudentBean {
9. If we want that a bean should be initialized for first time and then become immutable then its best idea to wire that bean with
constructor argument. Because via constructor argument they will be initialized but there is no other method to change them.
BeanPostProcessor:
BeanPostProcessor is a generic class which is used to apply generic action on each and every bean of the application. Flow of
execution of the method will be:
BeforeBeanPostProcessor->StartMethod->AfterBeanPostProcessor.->DestroyMethod.
11
return bean;
}
}
If we want to access field name and its value inside BeanPostProcessor then following code can be used:
BeanFactoryPostProcessor:
BeanFactoryPostProcessor class is called before BeanPostProcessor. This class is called before iniliazation of any bean. This class is
called only once. Whenever a bean is requested from application this class will be called.
12
public void postProcessBeanFactory(ConfigurableListableBeanFactory factory)
throws BeansException {
System.out.println("Bean Count:: "+factory.getBeanDefinitionCount());
System.out.println("Singleton Count:: "+factory.getSingletonCount());
System.out.println("Singleton Name:: "+factory.getSingletonNames());
String[] test=factory.getBeanDefinitionNames();
String[] inner;
System.out.println("Bean Defination Names");
for(int i=0;i<test.length;i++)
{
System.out.println("Bean Names:: "+test[i]);
inner= factory.getDependentBeans(test[i]);
for(int j=0;j<inner.length;j++)
{ System.out.println(" Dependent Names:: "+inner[j]);
}
}
test=factory.getSingletonNames();
System.out.println("Bean Defination Names Singlton");
for(int i=0;i<test.length;i++)
{
System.out.println("Bean Names:: "+test[i]);
}
<bean name="processorFactory"
class="com.GHS.common.controller.CommonBeanFactoryProcessor"/>
PropertyPlaceholderConfigurer:
This class is used to configure properties files. This is basically used in configuration files. To use this file we need to register in our
xml file. Complete sevlet.xml file after using PropertyPlaceholderConfigurer will be as under:
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
13
<bean name="/login.do" class="com.GHS.common.controller.CommonController"/>
<bean name="processor" class="com.GHS.common.controller.CommonBeanProcessor"/>
<bean name="processorFactory"
class="com.GHS.common.controller.CommonBeanFactoryProcessor"/>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>address.properties</value>
<value>house.properties</value>
<value>name.properties</value>
</list>
</property>
</bean>
<constructor-arg index="0">
<value>${name.lastName}</value>
</constructor-arg>
</bean>
</bean>
</beans>
14
Make sure that address.property, name.property and house.property are in application classpath.
If we single file then property name will be location and we have multiple file then propery name will be locations.
By this method we can use external configuration files with xml file only. If we want to use these file in java then there are several
method one of these method is DynamicPropertyReader.java. This class is written in java and can be download from huddle. in.
When you use this file into application we can read the properties as:
System.out.println("Dynamic Reader:"+DynamicPropertyReader.getDynamicProperty("address",
"address.state"));
System.out.println("Dynamic Reader:"+DynamicPropertyReader.getDynamicProperty("name",
"name.firstName"));
System.out.println("Dynamic Reader:"+DynamicPropertyReader.getDynamicProperty("house",
"house.number"));
Here first argument is the name of the property file and second argument is the property to be read.
ResourceBundleMessageSource
This is spring message reader. It is based on I18N standards.
Java’s support for parameterization and internationalization (I18N) of messages enables you to define one or more properties files
that contain the text that is to be displayed in your application. There should always be a default message file along with optional
language-specific message files.
All the properly files for different locale need to be configured in serlet.xml. Following code snippet need to be added into
servlet,xml.
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename"> <value>trainingtext</value>
</property>
</bean>
Only default property file name is specified into servlet.xml. All other name will be determined by Spring itself.
As we can see in above pix, property files with different language and country code has been added. As per the given locale
property files will be selected and populate the properties.
15
Object[] obj= new Object[2];
obj[0]="test";
obj[1]="test2";
Locale locale= Locale.ITALY;
Locale locale1= Locale.GERMANY;
First one is lookup code which is used to find the property being read.
Second parameter is the Object which contains various arguments that will be used by property being read.
Third parameter is Locale which will decide the property file to be selected. {0}, {1}
getMessage() may contain one more parameter which is default string . Whenever requested property done match with any property
then this default string will be returned.
Application Events:
Beans we are creating in our application are also capable to listening and publishing events.
The bean which is interested in listening event should implement ApplicationListener interface and bean which is interested in
publishing event should extend ApplicationEvent class. Here for example we are creaing Name.java as event listen and
TaxDetail.java as event publisher.
16
sBuff=sBuff+" "+this.firstName;
sBuff=sBuff+" "+this.middleName;
sBuff=sBuff+" "+this.lastName;
return sBuff;
}
}
}
private Long id;
private String tax;
private String taxYear;
Now from any controller class, where we can access ApplicationContext, we can publish an event of TaxDetail type.
beanFactory.publishEvent(new TaxDetail(this));
Above code will publish the event. Listner class will receive Event object which will be instance of TaxDetail object.
Event Publisher class should have constructor with one Object Argurment and this argument should be send to super class.
Whatever string we return from toString() method of publisher class, same string will be received by listner class.
package com.tutorialspoint;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStoppedEvent;
implements ApplicationListener<ContextStoppedEvent>{
System.out.println("ContextStoppedEvent Received");
17
}
import org.springframework.context.ApplicationEvent;
super(source);
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
implements ApplicationEventPublisherAware {
(ApplicationEventPublisher publisher){
this.publisher = publisher;
publisher.publishEvent(ce);
18
}
import org.springframework.context.ApplicationListener;
implements ApplicationListener<CustomEvent>{
System.out.println(event.toString());
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
ConfigurableApplicationContext context =
new ClassPathXmlApplicationContext("Beans.xml");
CustomEventPublisher cvp =
(CustomEventPublisher) context.getBean("customEventPublisher");
cvp.publish();
cvp.publish();
19
View Resolver
Whenever a handler code is executed user move to a new page (similar to struts). Controller may return complete path or a logical
name of the view. Spring provides various ways to solve the logical name of the views.
Full Path
Internal View Resolver
Bean Name View Resolver
Resource Bundle View Resolver
XML View Resolver
Full Path:
In this method controller return full path of the view. So no look up of the view is required.
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
In this method lookup is not required. Now complete view path will be calculated as:
So path will be
/WEB-INF/jsp/common/error.jsp
20
next.setViewName("errorFile");
next.addObject("loginType",event);
<bean id="beanNameViewResolver"
class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
views.property
errorFile.class=org.springframework.web.servlet.view.JstlView
errorFile.url =/WEB-INF/jsp/common/error.jsp
loginType.class=org.springframework.web.servlet.view.JstlView
loginType.url =/WEB-INF/jsp/common/error1.jsp
Config file
<bean id="bundleViewResolver"
class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="order">
<value>0</value>
</property>
<property name="basename">
<value>views</value>
</property>
</bean>
In this file basename property is used to get the name of the property file which contain view path. “order” property is used when
we are using multiple view handler.
By default locale might be en_US so property will be read from views_en_US.property file. As shown in diagram:
21
XML View Resolver:
In this method view information is stored in some xml files. Logical name return by controller is look up in these xml files.
Aspect:
An aspect is the cross-cutting functionality we are implementing. It is the aspect, or area, of our application we are modularizing.
Most common use Logging every information.
Advise:
22
Advice is the actual implementation of our aspect. It is advising your application of new behavior.
Advisor:
Advisor is collection of Join Point, advice and point cut.
Join Point:
A joinpoint is a point in the execution of the application where an aspect can be plugged in.
Point Cut:
A pointcut defines at what joinpoints advice should be applied. Advice can be applied at any joinpoint supported by the AOP
framework
Introduction:
An introduction allows you to add new methods or attributes to existing classes
Spring supports four type of advice.
Around
Before
After
Throw
Before implementing advise lets see our service classes or aspect where we want to weave our advises.
As we can see every service class should have interface otherwise advice can’t be applied to it.
Now let’s see the code for four advice.
23
System.out.println("::We are inside Before Advise:: calling "+method.getName());
}
}
}
}
}
All these Advice class require AOP jar. Because MethodBeforeAdvice, AfterReturningAdvice,
MethodInterceptor and ThrowsAdvice interfaces are taken from AOP jar.
import org.springframework.aop.ThrowsAdvice;
To call the function of our service classes we have written following code into common controller.
StudentDetail proxy=(StudentDetail)beanFactory.getBean("proxyBean");
proxy.printStudentDetail
proxy.printStudentAddress();
As you can see we are creating object of interfaces not actual service class. We get an error we create object of service class.
24
Now coding part of AOP has been over. Now we have to configure these aspects and service classes into servlet.xml which is main
part of AOP.
<bean id="StudentDetailImpl"
class="com.GHS.common.controller.Aspect.StudentDetailImpl"/>
<bean id="EmployeeDetailImpl"
class="com.GHS.common.controller.Aspect.EmployeeDetailImpl"/>
<bean id="welcomeAdvice" class="com.GHS.common.controller.Aspect.BeforeAdvise"/>
<bean id="thankAdvice" class="com.GHS.common.controller.Aspect.AfterAdvise"/>
<bean id="aroundAdvice" class="com.GHS.common.controller.Aspect.AroundAdvise"/>
<bean id="throwAdvice" class="com.GHS.common.controller.Aspect.ThrowAspect"/>
We have created bean for implementation class but not for interface. However while creating proxy bean we need Interface name
(see property ProxyInterfaces)
As we have create proxy bean StudentDetail interface so now whenever any method of this class will be invoked advice code be
executed as well.
Before advise:
Code of the BeforeAdvice will be executed before executing the code of calling method.
AfterAdvice:
Code of the AfterAdvice will be executed after executing the code of calling method.
ThrowAdvice:
Code of ThrowAdvice will be executed whenever calling method throw any exception which is not handled in calling method.
AroundAdvice:
AroundAdvice comes with more capabilities. With Around Advice we can manually call the method and set our logic before and
after method invocation.
invoke.getMethod()
invoke.getArgument()[0];
With these instructions we can call each and every property of the target method.
After and Before advice allowed us to change return object value but does not allow to return a completely new object i.e we can
not change return type. However with Around Advice we can return a completely new object.
25
As we have applied all the advice to this class so flow will be as:
So we run the code of Common Controller then output will be like this:
PointCuts:
Whenever we apply these advices on any class then it is applied to every method of the class. Spring PointCuts provide us
functionality so that we can choose which class and which method particular advice should be applied.
PointCuts can be static and dynamic.
We can create out own pointcuts by implementing interfaces.
Static PointCuts:
NameMatchMethodPointcut
RegexpMethodPointcut
<bean id="NamePointcutAdvisor"
class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="mappedNames">
<list>
<value>*Address</value>
</list>
</property>
<property name="advice">
<ref bean="welcomeAdvice"/>
</property>
</bean>
<bean id="NamePointcutAdvisor2"
class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="mappedNames">
<list>
<value>*Detail</value>
26
</list>
</property>
<property name="advice">
<ref bean="thankAdvice"/>
</property>
</bean>
We have defined two Pointcut in above code. First Point define that welcome advice will be applied to all the method ending with
Detail.
We have mention these pointcuts as an interceptorNames of proxybean. Now welcome and thank advice is applied on method level
not on the class level.
One point contain only one advise.
NameMatchMethodPointcut allow us to use * but it will match the pattern with only Mehtod name not with fully qualified class
name. To over come this problem we have another PointCut called RegexpMethodPointcut
<bean id="regAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref bean="welcomeAdvice"/>
</property>
<property name="pattern">
<value>.*common.*</value>
</property>
</bean>
<property name="interceptorNames">
<list> <value>regAdvisor</value>
</list>
</property>
However our regAdvisor has been applied to all the classes of the common package. If common contain other packages then
regAdvisor will be applied to them as well.
27
/ Escapes any \.setFoo. matches bar.setFoo ,
regular but not and
expression setFoo
symbol
Before using RegexpMethodPointcutAdvisor class in your application we need to add Jakarta Commons ORO in our lib directory.
1. cglib-full-2.0.2.jar
2. aopalliance.jar
3. jakarta-oro-2.0.8.jar
Spring provide one dynamic pointcut as well ControlFlow-Pointcut. This pointcut is hardly use as it takes so my execution
time.
As you can see if we want to apply any advice to a class we need to create a proxy and then associate advice/pointcut/advisor to it
which is very length and tedious job.
To overcome this problem Spring comes auto proxy classess. Spring provide 2 auto proxy creater.
BeanNameAutoProxyCreator
DefaultAdvisorAutoProxyCreator
<bean id="throwAdviceProxyCreator"
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list> <value>*Detail*</value>
</list>
</property>
<property name="interceptorNames">
<list> <value>welcomeAdvice</value>
<value>thankAdvice</value>
</list>
</property>
</bean>
Now BeanNameAutoProxyCreator will apply these advise to all the beans which matched the patter. These advise will
applied to all the method of the selected class.
Here interceptorNames can be pointcut names. So if provide point cuts then advise will be applied to selected class with
selected method.
DefaultAdvisorAutoProxyCreator will not take any argument or parameter. When all the beans has been read by application
context then this AutoProxy start its working.
If you have configured any PointCut in servlet.xml then this AutoProxy take this pointcut and try to apply this every bean in the
BeanFactory. So here if you define a pointcut, no need to write proxyBean for any Service class however this job will be performed
by AutoProxy.
<bean id="regAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref bean="welcomeAdvice"/>
</property>
<property name="pattern"> <value>.*print.*</value>
28
</property>
</bean>
<bean id="regAdvisor2"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref bean="thankAdvice"/>
</property>
<property name="pattern"> <value>.*print.*</value>
</property>
</bean>
<bean id="autoProxyCreator"
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
As you can view the code, autoProxyCreator does not take any input parameter.
Scheduler:
Spring comes with inbuilt support for scheduling the job. Spring provides two types of scheduler:
TimerTask
Quartz Scheduler
Timer Task:
Timer Task is same to java timer class. To create a timer class we need to implement TimerTask interface. This interface provide
run() method which will be executed.
import java.util.TimerTask;
public class GenerateReport extends TimerTask {
public static int count=0;
public static int getCount() {
return count;
}
public void run() {
System.out.println("::Job Executed:: Counter= "+count);
count++;
}
<bean id="scheduledReportTask"
class="org.springframework.scheduling.timer.ScheduledTimerTask" scope="singleton">
29
<property name="timerTask">
<ref bean="reportTimerTask"/>
</property>
<property name="period">
<value>1000</value>
</property>
<property name="delay">
<value>20000</value>
</property>
</bean>
Second we need to schedule the task with ScheduledTimerTask class. This has two properties.
In TimerTask class we can not state at which time job should start first. However we can state delay in first execution but can’t
specify exact timing. This problem can be overcome with Quartz Scheduler.
To use Quartz our service class need to extends QuartzJobBean class. Before using make sure that you have added quartz-all-1.6.5
file into lib directory.
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
30
}
<bean id="reportALLTimerTask"
class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass">
<value>com.GHS.common.controller.GenerateAllReport</value>
</property>
</bean>
<bean id="scheduledReportALLTask"
class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail">
<ref bean="reportALLTimerTask"/>
</property>
<property name="startDelay">
<value>25000</value>
</property>
<property name="repeatInterval">
<value>1000</value>
</property>
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="scheduledReportALLTask"/>
</list>
</property>
</bean>
As you can see creating bean of service is different in quartz. Bean is created of type JobDetailBean which take argument of Service
class.
scheduledReportALLTask is very similar to TimerTask. Spring provide CronTriggerBean to schedule Quartz
effectively.
<bean id="cronReportTrigger"
class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<ref bean="reportALLTimerTask"/>
</property>
<property name="cronExpression">
<value>35 * * * * ?</value>
</property>
</bean>
CronTriggerBean got special property called cronExpression which has 6 paramter optionally 7.
1 Second (0–59)
2 Minutes (0–59)
31
3 Hours (0–23)
4 Day of month (1–31)
5 Month (1–12 or JAN–DEC)
6 Day of week (1–7 or SUN–SAT)
7 Year (1970–2099)
Day of the week and Day of the month are mutually exclusive. So we can specify only one at a time and other will be marked as ?.
Expression Meaning
0 0 10,14,16 * * ? Every day at 10 a.m., 2 p.m., and 4
p.m.
0 0,15,30,45 * 1–10 Every 15 minutes on the first 10 days
*? of every month
30 0 0 1 1 ? 2012 30 seconds after midnight on January
1, 2012
0 0 8-5 ? * MON–FRI Every working hour of every business
day
So 35 * * * * ? will be read as 35 second of any minute of any hour of any day of month of any year.
Points:
1. Spring is light weight inversion of control.
2. Spring Provide inbuilt JDBC abstraction.
3. It has powerful transaction management tool.
4.
ApplicationContext can be inilized as
32
ApplicationContext ctx = new ClasspathXmlApplicationContext(new String[] {
"applicationContext-web.xml",
"applicationContext-services.xml",
"ApplicationContext-dao.xml" } );
<beans>
<import resource="data-access.xml"/>
<import resource="services.xml "/>
<import resource="resources/messgeSource.xml"/>
<bean id="..." class="..."/>
</beans>
33