0% found this document useful (0 votes)
13 views33 pages

First SPRING

Spring quick notes

Uploaded by

Sonu Mehta
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views33 pages

First SPRING

Spring quick notes

Uploaded by

Sonu Mehta
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 33

Step-By-Step:

 Spring is based on beans. Every thing in Spring is designed as beans. This is basically used in business layer.

1. Open eclipse ganymade and click on new-Dynamic web Project.


2. Fill the project name and click on next and then click on finish button.
3. Next step is to put the required JAR files in lib folder under Webcontent/WEB-INF

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>

In web.xml display name tag works as caption for your application.

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.

Servlet tag is required if you are using spring as web application.

5. Next step is to create the required bean classes for spring.


We are creating 3 beans Name. Address and Student.
Name beans is:
public class Name {

private String firstName;


private String middleName;
private String lastName;
private String initial;
//getter setter for these properties and toString method.

}
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>

<bean name="/login.do" class="com.GHS.common.controller.CommonController"/>

<bean name="name" class="com.GHS.common.beans.Name"


p:initial="Mr."
p:firstName="Sonu"
p:middleName="Kumar"

3
p:lastName="Mehta"
/>

<bean name="address" class="com.GHS.common.beans.Address"


p:state="Haryana"
p:country="India"
p:city="Sirsa"
p:VPO="Khuyian Malkana"
p:street="Main Street"
p:houseNumber="631"
scope="prototype"
/>

<bean name="student" class="com.GHS.student.beans.StudentBean"


p:id="testID"
scope="prototype">
<property name="name">
<ref bean="name"/>
</property>
<property name="address">
<ref bean="address"/>
</property>
</bean>
</beans>
Here scope property of a bean define the bean is static or not. If scope property is defined as SINGLETON bean is static and only
one bean is generated of whole application. Whenever any process access this bean it will get same object. If scope property is
defined as PROTOTYPE then bean not static and a new instance is created whenever a process access it.

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.

BeanFactory factory =new XmlBeanFactory(new FileInputStream("beans.xml"));

ApplicationContext context =new FileSystemXmlApplicationContext("c:/foo.xml");

ApplicationContext has many advantage over BeanFactory


 Application contexts provide a means for resolving text messages, including support for internationalization (I18N) of
those messages.
 Application contexts provide a generic way to load file resources, such as images.
 Application contexts can publish events to beans that are registered as listeners.
3. ApplicationContext can be configured in three ways:
 ClassPathXmlApplicationContext—Loads a context definition from an XML file located in the class path, treating
context definition files as class path resources.
 FileSystemXmlApplicationContext—Loads a context definition from an XML file in the filesystem.
 XmlWebApplicationContext—Loads context definitions from an XML file contained within a web application.

4. Wiring Simple Bean


public class Name {

private String firstName;


private String middleName;
private String lastName;
private String initial;

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;

}
}

Wiring for this bean will be done as under:


<bean name="name" class="com.GHS.common.beans.Name"
p:initial="Mr."
p:firstName="Sonu"
p:middleName="Kumar"
p:lastName="Mehta"
/>
Every property is initializing here. We can initlize property by two ways either by constructor or by setter methods.

Above is example of initilise the property with setter method of a bean.

If we want to initlilze properties with contructor then we have write as:

<bean name="name" class="com.GHS.common.beans.Name">


<constructor-arg index="1">
<value>CONSonu</value>
</constructor-arg>

<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;
}

Corresponding constructor needs to be in bean class.

Index attribute in constructor tag specify the index of the argument in constructor method.

5. We can refer to other bean :


public class StudentBean {

private String id;


private Name name;
private Address address;

public void start(){


System.out.println("StudetnStart Method called");
}
public void end(){
System.out.println("StudetnEnd Method called");
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Name getName() {
return name;
}
public void setName(Name name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String toString() {
String sBuff = new String();
sBuff="ID:: "+this.id;
sBuff=sBuff+"::"+"Name:: "+this.name.toString();
sBuff=sBuff+"::"+"Address:: "+this.address.toString();
return sBuff;
}
}

To wire this bean with XML we need to write as:

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>

Here three new attributes are present:

Init-method: Corresponding method will be called before initialization start or we can say before bean given to application for use.

Destroy-method: Corresponding method will be called before destroying the object

Scope: This property will specify how to generate bean.


Scope property can have two values either prototype or singleton.

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.

By default singletop property is considered.

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>

Here we can not reuse student service bean.

7. Spring allow four type of collection.


<list>, <set>, <map> and <props>
List:
Suppose we have bean class like:

public class StudentBean {

private String id;


private Name name;
private Address address;
List list;
}

So to wire list variable we need to add following snippet to servlet xml.

<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 {

private String id;


private Name name;
private Address address;
Set list;
}

So to wire list variable we need to add following snippet to servlet xml.


<property name="list">
<set>
<ref bean="name"/>
<ref bean="address"/>
</set>
</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.

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 {

private String id;


private Name name;
private Address address;
Map list;
}

So to wire list variable we need to add following snippet to servlet xml.


<property name="list">
<map>
<entry key="name">
<ref bean="name"/>
</entry>
<entry key="address">
<ref bean="address"/>
</entry>
</map>
</property>

One extra tag entry is given to wire a Map.

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 {

private String id;


private Name name;
private Address address;
Properties list;
}

So to wire list variable we need to add following snippet to servlet xml.


<property name="list">
<props>
<prop key="name">Sonu Mehta</prop>
<prop key="address">Sirsa</prop>
</props>
</property>

8. We can explicitly set null value to any object.


<property name="name"><null/><property>

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.

To utilize bean post processor we need to do two task

 Create a new class which will implements BeanPostProcessor Interface.


 Register this class with applicationcontext.

New class will be created as under:

public class CommonBeanProcessor implements BeanPostProcessor {

public Object postProcessAfterInitialization(Object bean, String name)


throws BeansException {
System.out.println("After:: "+name);
return bean;
}

public Object postProcessBeforeInitialization(Object bean, String name)


throws BeansException {
System.out.println("Before:: "+name);

11
return bean;
}
}

Registry under servlet.xml will be done as under:

<bean name="processor" class="com.GHS.common.controller.CommonBeanProcessor"/>

If we want to access field name and its value inside BeanPostProcessor then following code can be used:

public Object postProcessAfterInitialization(Object bean, String name)


throws BeansException {
if(name.equalsIgnoreCase("address"))
{
System.out.println("After:: "+name);
System.out.println("Name Bean called");
Field[] fields = bean.getClass().getDeclaredFields();
try {
for(int i=0; i < fields.length; i++) {
if(fields[i].getType().equals( java.lang.String.class))
{fields[i].setAccessible(true);
String original = (String) fields[i].get(bean);
System.out.println("Field Name:: "+fields[i].getName());
System.out.println("Field Value:: "+original);
fields[i].set(bean, "TEST");
System.out.println("New Value:: "+fields[i].get(bean));
}
}
} catch (IllegalAccessException e) { e.printStackTrace();
}
}
return bean;
}

Here returning a bean is compulsory.


Before accessing any field we need to call setAccessible(true) for that field.
Field is a class from java.lang.reflect.Field.
There are several other method as well which can be utilized as well:
Bean.getClass.getName: Fully qualified class name
Bean.getClass.getPackageName: fully qualified package name
Bean.getClass.getContructors: Returns all the constructors. As we use Field class to hold all the fields same way we need to use
Contructor class to hold all the constructors.

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.

To utilize bean post processor we need to do two tasks

 Create a new class which will implements BeanFactoryPostProcessor Interface.


 Register this class with applicationcontext.

New class will be created as under:


public class CommonBeanFactoryProcessor implements BeanFactoryPostProcessor {

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]);
}

Registry under servlet.xml will be done as under:

<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:

<?xml version="1.0" encoding="UTF-8"?>


<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>

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>

<bean name="name" class="com.GHS.common.beans.Name" scope="prototype">


<constructor-arg index="1">
<value>${name.firstName}</value>
</constructor-arg>

<constructor-arg index="0">
<value>${name.lastName}</value>
</constructor-arg>
</bean>

<bean name="address" class="com.GHS.common.beans.Address"


p:state="${address.state}"
p:country="${address.country}"
p:city="${address.city}"
p:VPO="Khuyian Malkana"
p:street="Main Street"
p:houseNumber="${house.number}"
scope="prototype">
</bean>

<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>
<property name="list">
<props>
<prop key="name">Sonu Mehta</prop>
<prop key="address">Sirsa</prop>
</props>
</property>

</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.

Trainingtext_de_DE.properties contain following properties:

course=classDE {0} and {1}


student=studentDE first={0} and second={1}
computer=computerDE

To access these properies in java we need following code snippet.

15
Object[] obj= new Object[2];
obj[0]="test";
obj[1]="test2";
Locale locale= Locale.ITALY;
Locale locale1= Locale.GERMANY;

System.out.println("Bean Message:: "+beanFactory.getMessage("course", obj,locale));


System.out.println("Bean Message:: "+beanFactory.getMessage("student", obj,locale1));

Here getMessage() method accept 3 parameter.

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.

public class Name implements ApplicationListener{

private String firstName;


private String middleName;
private String lastName;
private String initial;

public void onApplicationEvent( ApplicationEvent event) {


if(event instanceof org.springframework.context.event.ContextClosedEvent)
{
System.out.println("::Closed Event caught::");
}
if(event instanceof org.springframework.context.event.ContextRefreshedEvent)
{
System.out.println("::Refreshed Event caught::");
}
if(event instanceof com.GHS.common.beans.TaxDetail){
System.out.println("::Tax Event caught::");
}
}

Name(String first,String last)


{
firstName=first;
lastName=last;
}

//Setter getter for Data Member


public String toString() {
String sBuff = new String();
sBuff=this.initial;

16
sBuff=sBuff+" "+this.firstName;
sBuff=sBuff+" "+this.middleName;
sBuff=sBuff+" "+this.lastName;
return sBuff;
}
}

Event publisher class TaxDetail.java will look like as:

public class TaxDetail extends ApplicationEvent{

public TaxDetail(Object source) {


super(source);

}
private Long id;
private String tax;
private String taxYear;

//Setter Getter for data members


public String toString()
{
String detail="This is DetailText";
return detail;
}
}

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;

public class CStopEventHandler

implements ApplicationListener<ContextStoppedEvent>{

public void onApplicationEvent(ContextStoppedEvent event) {

System.out.println("ContextStoppedEvent Received");

17
}

import org.springframework.context.ApplicationEvent;

public class CustomEvent extends ApplicationEvent{

public CustomEvent(Object source) {

super(source);

public String toString(){

return "My Custom Event";

import org.springframework.context.ApplicationEventPublisher;

import org.springframework.context.ApplicationEventPublisherAware;

public class CustomEventPublisher

implements ApplicationEventPublisherAware {

private ApplicationEventPublisher publisher;

public void setApplicationEventPublisher

(ApplicationEventPublisher publisher){

this.publisher = publisher;

public void publish() {

CustomEvent ce = new CustomEvent(this);

publisher.publishEvent(ce);

18
}

import org.springframework.context.ApplicationListener;

public class CustomEventHandler

implements ApplicationListener<CustomEvent>{

public void onApplicationEvent(CustomEvent event) {

System.out.println(event.toString());

import org.springframework.context.ConfigurableApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {

public static void main(String[] args) {

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.

ModelAndView next= new ModelAndView();


next.setViewName("/WEB-INF/jsp/common/error.jsp");
next.addObject("xml",s);

In this method no changes in config required.

Internal View Resolver:


This is very basic view resolver which comes with very less functionality. In this method logical name return by controller is treated
as a part of actual view path. In config file Internal View Resolver is defined as follows:

<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>

Corresponding changes in controller will be done as

ModelAndView next= new ModelAndView();


next.setViewName("common/error");
next.addObject("loginType",event);

In this method lookup is not required. Now complete view path will be calculated as:

prefix + logicalName + suffix.

/WEB-INF/jsp/ + common/error + .jsp

So path will be
/WEB-INF/jsp/common/error.jsp

Bean Name View Resolver:


This resolver provides a bit more functionality. In this method logical name is treated as key to actual view path.
Logical name return by controller refer to a bean in config file which contain actual path of the view.

ModelAndView next= new ModelAndView();

20
next.setViewName("errorFile");
next.addObject("loginType",event);

Config file changes will be:

<bean id="beanNameViewResolver"
class="org.springframework.web.servlet.view.BeanNameViewResolver"/>

<bean id="errorFile" class=" org.springframework.web.servlet.view.JstlView">


<property name="url">
<value>/WEB-INF/jsp/common/error1.jsp
</value>
</property>
</bean>
As we can see that controller return “errorFile” view name and same bean name present in config file.
Here class and url property is very important while creating bean of the view path.
“class” property will specify the transformer name that will be used for current page.
“url” property will specify location of the view page.

Resource Bundle View Resolver:


This is very powerful view Resolver. It can select the view depending upon locale. In this method view path is defined in some
external property file. Logical name from controller is looked up in these property file as per locale.

We have created property as under:

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

In property file we need to specify both class and url.


controller class
ModelAndView next= new ModelAndView();
next.setViewName("errorFile");
next.addObject("loginType",event);

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.

<bean id="xmlFileViewResolver" class="org.springframework.web.


servlet.view.XmlFileViewResolver">
<property name="location">
<value>/WEB-INF/training-views.xml</value>
</property>
</bean>

Aspect Oriented Programming:


AOP is another way of modularizing the application and making application component loosely coupled.

There are five main properties of AOP.


 Aspect
 Advise
 Join Point
 Introduction
 Advisor
 Point Cut

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.

public interface StudentDetail {


void printStudentDetail();
void printStudentAddress() throws Exception;
}

public class StudentDetailImpl implements StudentDetail {

public void printStudentDetail() {


System.out.println("We are inside printStudentDetail() ");
}

public void printStudentAddress()throws Exception {


System.out.println("We are inside printStudentAddress() ");
}
}

public interface EmployeeDetail {


public void printEmployeeDetail();
}

public class EmployeeDetailImpl implements EmployeeDetail{


public void printEmployeeDetail() {
System.out.println("We are inside printEmployeeDetail() ");
}
}

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.

public class BeforeAdvise implements MethodBeforeAdvice {


public void before(Method method, Object[] parameter, Object target)
throws Throwable {
if(target instanceof com.GHS.common.controller.Aspect.StudentDetailImpl)
System.out.println("Student detail found");

23
System.out.println("::We are inside Before Advise:: calling "+method.getName());
}

public class AfterAdvise implements AfterReturningAdvice {


public void afterReturning(Object returnValue, Method method, Object[] parameter,Object
target) throws Throwable {
System.out.println("::We are inside After Advise:: we have execute::
"+method.getName());

}
}

public class AroundAdvise implements MethodInterceptor {


public Object invoke(MethodInvocation invoke) throws Throwable {
//invoke.getArgument()[0];
System.out.println("::We are inside Arround Advise:: we going to execute
"+invoke.getMethod().getName());
invoke.proceed();
System.out.println("::We are inside Arround Advise:: we have execute
"+invoke.getMethod().getName());
return null;
}

public class ThrowAspect implements ThrowsAdvice {


public void afterThrowing(Method method, Object[] args, Object target, Exception e) {
System.out.println("::We are inside Throw Advise:: Exception name:: "+e.toString());
System.out.println("::We are inside Throw Advise:: Method name:: "+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;

This jar can be taken from huddle.

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();

EmployeeDetail employee= (EmployeeDetail)beanFactory.getBean("EmployeeDetailImpl");


employee.printEmployeeDetail();

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.

To configure we need to write following code snippet:

<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"/>

<bean id="proxyBean" class="org.springframework.aop.framework.ProxyFactoryBean">


<property name="proxyInterfaces">
<value>com.GHS.common.controller.Aspect.StudentDetail</value>
</property>
<property name="interceptorNames">
<list>
<value>welcomeAdvice</value> <value>thankAdvice</value>
<value>aroundAdvice</value> <value>throwAdvice</value>
</list>
</property>
<property name="target">
<ref bean="StudentDetailImpl"/>
</property>
</bean>

We have created bean for implementation class but not for interface. However while creating proxy bean we need Interface name
(see property ProxyInterfaces)

Here interceptorNames can be advice and pointcut or advisor.

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:

welcomeAdvice->AroundAdvice(prelogic,functioncall, postlogic)->ThrowAdvice(if required)->ThankAdvice.

So we run the code of Common Controller then output will be like this:

::We are inside Before Advise:: calling printStudentDetail


::We are inside Arround Advise:: we going to execute printStudentDetail
We are inside printStudentDetail()
::We are inside Arround Advise:: we have execute printStudentDetail
::We are inside After Advise:: we have execute:: printStudentDetail

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="proxyBean" class="org.springframework.aop.framework.ProxyFactoryBean">


<property name="proxyInterfaces">
<value>com.GHS.common.controller.Aspect.StudentDetail</value>
</property>
<property name="interceptorNames">
<list> <value>NamePointcutAdvisor</value>
<value>NamePointcutAdvisor2</value>
</list>
</property>
<property name="target">
<ref bean="StudentDetailImpl"/>
</property>
</bean>

<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>

We will update our proxy bean as:

<property name="interceptorNames">
<list> <value>regAdvisor</value>
</list>
</property>

Fully qualified path of StudentBeanImpl class is


com.GHS.common.controller.Aspect.StudentDetailImpl

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.

Following wild card character are allowed in RegExpresion:


Symbol Description Example
. Matches any setFoo. matches setFooB, but not
single setFoo or
character setFooBar
+ Matches the setFoo.+ matches setFooBar and
preceding setFooB,
character one but not setFoo
or more times
* Matches the setFoo.* matches setFoo,
preceding setFooB and
character zero setFooBar
or more times

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++;
}

To configure this report into servlet.xml we need to do three tasks:

<bean id="reportTimerTask" class="com.GHS.common.controller.GenerateReport"


scope="singleton"/>

<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>

<bean class="org.springframework.scheduling.timer.TimerFactoryBean" scope="singleton">


<property name="scheduledTimerTasks">
<list>
<ref bean="scheduledReportTask"/>
</list>
</property>
</bean>

First we need to create the bean of our service class.

Second we need to schedule the task with ScheduledTimerTask class. This has two properties.

Period property specifies the interval of the job execution.


Delay property specifies delay in first execution of the job. For example when server starts, then after how much time it should
execute the job first time.

Third and last we need to start the timer.

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;

public class GenerateAllReport extends QuartzJobBean {


public static int counter=0;
public static int getCount() {
return counter;
}
protected void executeInternal(JobExecutionContext arg0)
throws JobExecutionException {
System.out.println("::Quartz Job Executed:: Counter= "+counter);
counter++;
}

30
}

To configure Quartz job into servlet.xml require three different tasks.

<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>

DefaultListableBeanFactory factory = new DefaultListableBeanFactory();


XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
ClassPathResource res = new ClassPathResource("beans.xml");
reader.loadBeanDefinitions(res);
res = new ClassPathResource("beans2.xml");
reader.loadBeanDefinitions(res);
// now use the factory

5. Events are operated synchronously in Spring


6. We can use more than one view resolver in spring.
<bean id="specialViewResolver"
class="org.springframework.web.servlet.view.ResourceBundl eViewResolver">
<property name="order">
<value>0</value>
</property>
<property name="basename">
<value>views</value>
</property>
</bean>
<bean id="typicalViewResolver"
class="org.springframework.web.servlet.view.InternalResou rceViewResolver">
<property name="viewClass">
<value>org.springframework.web.servlet.view.JstlView</value>
</property>
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>

33

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy