Spring AOP Notes (Aspect Oriented Programming in Spring) PDF
Spring AOP Notes (Aspect Oriented Programming in Spring) PDF
Sathish
Introduction to AOP
The Real Problem
Since AOP is relatively new, this section devotes time in explaining the need for Aspect
Oriented Programming and the various terminologies that are used within. Let us look into the
traditional model of before explaining the various concepts.
The above code models a simple Account Object that provides services for deposit and
withdrawal operation in the form of Account.deposit() and Account.withdraw() methods.
Suppose say we want to add some bit of the security to the Account class, telling that only
users with BankAdmin privilege is allowed to do the operations. With this new requirement
being added, let us see the modified class structure below.
Account.java
public class Account{
public long deposit(long depositAmount){
User user = getContext().getUser();
if (user.getRole().equals("BankAdmin"){
newAmount = existingAccount + depositAccount;
currentAmount = newAmount;
} return currentAmount;
}
public long withdraw(long withdrawalAmount){
1
Page
if (user.getRole().equals("BankAdmin"){
if (withdrawalAmount<=currentAmount){
currentAmount=currentAmount-withdrawalAmount;
}
return currentAmount;
}
}
Assume that getContext().getUser() someway gives the current User object who is invoking the
operation. See the modified code mandates the use of adding additional if condition before
performing the requested operation. Assume that another requirement for the above Account
class is to provide some kind of Logging and Transaction Management Facility. Now the code
expands as follows,
Account.java
transaction.begin();
try{
if (user.getRole().equals("BankAdmin"){
currentAmount = newAmount;
transaction.commit();
}catch(Exception exception){
transaction.rollback();
return currentAmount;
transaction.begin();
try{
if (user.getRole().equals("BankAdmin"){
if (withdrawalAmount<=currentAmount){
currentAmount=currentAmount-withdrawalAmount;
return currentAmount;
The above code has so many dis-advantages. The very first thing is that as soon as new
requirements are coming it is forcing the methods and the logic to change a lot which is against
the Software Design. Remember every piece of newly added code has to undergo the Software
Development Lifecycle of Development, Testing, Bug Fixing, Development, Testing, …. This,
certainly cannot be encouraged in particularly big projects where a single line of code may have
multiple dependencies between other Components or other Modules in the Project.
Let us re-visit the Class Structure and the Implementation to reveal the facts. The Account class
provides services for depositing and withdrawing the amount. But when you look into the
implementation of these services, you can find that apart from the normal business logic, it is
doing so many other stuffs like Logging, User Checking and Transaction Management. See the
pseudo-code below that explains this
From the above pseudo-code, it is clear that Logging, Transaction Management and User
Checking which are never part of the Deposit or the Service functionality are made to embed in
3
the implementation for completeness. Specifically, AOP calls this kind of logic that cross-cuts or
Page
overlaps the existing business logic as Concerns or Cross-Cutting Concerns. The main idea of
AOP is to isolate the cross-cutting concerns from the application code thereby modularizing
them as a different entity. It doesn’t mean that because the cross-cutting code has been
externalized from the actual implementation, the implementation now doesn’t get the
required add-on functionalities. There are ways to specify some kind of relation between the
original business code and the Concerns through some techniques which we will see in the
subsequent sections.
In Spring AOP Middleware services are also called as Aspects or cross cutting concerns because
they reside outside the application logics but will executed along with the application logics.
Instead of writing Middleware service logics directly with application code it is recommended to
separate them from application code and apply them on application code using
XML, Annotations by taking the support of Spring AOP.
AOP Terminologies:
1. Aspect
2. Advice
3. Advisor
4. Point cut
5. Wiring
6. Weaving
7. JoinPoint
8. Target Object
9. Proxy Object.
1. Aspect: Contains the plan of implementing Middleware Service
2. Advice: It is the practical implementation of Middleware Services. The position in business
methods where advices are configured are called as Join Point
EX: Beginning of the business methods, end of the business methods. Exception is resided in
the business method and etc.,
public void someBussinessOperation(BusinessData data){
//MethodStart-->possible aspect code here like logging.
try{
//Original Bussiness Logic Here.
}catch(Exception e)
{
//Exception-->Aspect code here when some exception is raised
}
finally
{
//Finally-->Even Possible to have aspect code at this point too.
}
//MethodEnd-->Aspect code here in the End of a method.
4
}
Page
It is not Necessary that an Aspect should be applied to all the possible Join Points.
If we call business methods on Target object only business logic will be executed. If we call
business methods on Proxy Object the business logic will be executed along with Middleware
services. Generally we never apply Middleware services in small scale project development.
While we apply Middleware services in medium and large scale projects.
Spring AOP supports only method level Aspect oriented programming that means it does not
support Field level Aspect oriented programming.
Spring beans borrowed AOP facilities from Alliance company but entire API is inbuilt of Spring
software.
Advice: Advice is the code that implements the Aspect.. In general an Aspect defines the
functionality in a more abstract manner. But, Advice that provides a Concrete Implementation
for the Aspect.
Note:
The org.springframework.aop.framework.ProxyFactoryBean class converts given Spring Bean
class object to Proxy object and returns that object.
Note: When business methods are called on Proxy object the business logic will be executed
along with Advices.
1. BeforeAdvice:
Before Advice is used to intercept before the method execution starts. In AOP, Before
Advice is represented in the form of org.springframework.aop.MethodBeforeAdvice.
For example a sytem makes security checks before allowing then to accesing resources.
In such a case, we can have a Before Advice that contains code whilch implements
Authentication logic
consider the following piece of code.
EX:
public class Authentication implements MethodBeforeAdvice
// Here MethodBefore Adviceis manadatory to make the Java class BeforeAdvice{
public void before(Method method, Object[] args, Object target) throws Throwable
{
//place the Authentication logic here.
}
}
Above class implements MethodBeforeAdvice, there by telling before method will be called
before the execution of the method call. Note that the java.lang.reflect.Method method object
represents target method to be invoked, Object[] args refers to the various arguments that are
passed on the method and target refers to the object which is calling the method.
The following Sequence diagram describing the operations when before advice and joinpoint
6
The following Sequence diagram describing the operations when before advice exection
and terminates abnormally, that is , throwing exception
As shown in fig. in the case where before advice throws an exception then an exception is
thrown to the client without continuing further the interceptor's execution and the target
object method.
Working with before advice :-
In this section we will develop an example to demonstrate how to write an advice that has
to be applied before the joinpoint execution, and how to configure it according to the
spring 1.2 low-level approach. In this example we will implement the well known simple
customer service which requires some seconday logics like logging.
7
Page
Naresh i Technologies Spring AOP Notes By Mr. Sathish
CustomerService.java
package com.nareshit.service;
public interface CustomerService {
public String printName();
public String printUrl();
public void printException()throws InterruptedException;
}
CustomerServiceImpl.java
package com.nareshit.service;
public class CustomerServiceImpl implements CustomerService {
private String name, url;
public void setName(String name) {
this.name = name;
}
public void setUrl(String url) {
this.url = url;
}
public String printName() {
System.out.println("Bussiness Method : PrintName () :");
return name;
}
public String printUrl() {
System.out.println("Bussiness Method : PrintURL () :");
return url;
}
public void printException() throws InterruptedException {
System.out.println("Bussiness Method : PrintException () :");
throw new InterruptedException("Don't Sleep in the class room");
}
}
8
Page
Naresh i Technologies Spring AOP Notes By Mr. Sathish
LoggingBeforeAdvice.java
package com.nareshit.advices;
import java.lang.reflect.Method;
import org.apache.log4j.Logger;
import org.springframework.aop.MethodBeforeAdvice;
public class LoggingBeforeAdvice implements MethodBeforeAdvice{
public void before(Method method, Object[] arg, Object target)
throws Throwable {
Logger logger=Logger.getLogger(target.getClass().getName());
logger.info("Enterted into :"+target.getClass().getName()+" class "+method.getName()+"
Method With the arguments "+arg.length);
}
}
log4j.properties
applicationContext.xml
"com/nareshit/config/applicationContext.xml");
Naresh i Technologies Spring AOP Notes By Mr. Sathish
Upon execution of the above application, the log file will be generated and the output and
logfile content as shown in the following fig’s will be presented
output
Logfile :-
10
Page
Naresh i Technologies Spring AOP Notes By Mr. Sathish
The following diagram helps to understand the above example execution flow.
As shown in the above fig the spring container dynamically creates a proxy object through
the ProxyFactoryBean , where the dynamically built Proxy class implements all the interfaces
given under the proxyInterfaces list (in the above example one interface
com.nareshit.service.CustomerService) . All the methods are implemented to invoke the
configured interceptors(advices) and the method on the given target Object.
Note :-
In Spring 2.0 if we do not configure proxyInterfaces property , then ProxyFactoryBean builds the
proxy class,implementing all the interfaces implemented by the target object class.
In case the target object does not implement an interfaces then it extends the target Object
class.Make sure that in this case, the target object class has no-arg constructor where even the
CGLIB.jar file is set into the classpath.
2. AfterAdvice:
After Advice will be useful if some logic has to be executed before Returning the Control within
a method execution. This advice is represented by the interface
org.springframework.aop.AfterReturningAdvice. For example, it is common in Application to
11
Delete the Session Data and the various information pertaining to a user, after he has logged
out from the Application. These are ideal candidates for After Advice.
Page
Naresh i Technologies Spring AOP Notes By Mr. Sathish
EX: CleanUpOperatoin.java
Note that, afterReturning() method will be called once the method returns normal execution.
If some exception happends in the method execution the afterReturning method will never be
called.
12
Page
Naresh i Technologies Spring AOP Notes By Mr. Sathish
In this section we will develop an example to demonstrate how to develop and configure
afterReturning advice.
CustomerService.java
package com.nareshit.service;
public interface CustomerService {
public String printName();
public String printURL();
public void printException();
}
13
Page
Naresh i Technologies Spring AOP Notes By Mr. Sathish
CustomerServiceImpl.java
package com.nareshit.service;
import org.springframework.beans.factory.annotation.Value;
LoggingAfterAdvice.java
package com.nareshit.advices;
import java.lang.reflect.Method;
import org.apache.log4j.Logger;
import org.springframework.aop.AfterReturningAdvice;
public class LoggingAfterAdvice implements AfterReturningAdvice{
private static Logger logger=
Logger.getLogger(LoggingAfterAdvice.class);
@Override
public void afterReturning(Object returnValue,
Method method, Object[] arguments,
Object target) throws Throwable {
logger.info("After executing : "+target.getClass().getName()+" class Bussiness Method
:"+method.getName()+" return value : "+returnValue);
}
}
14
Page
myBeans.xml
Test.java
package com.nareshit.client;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.nareshit.service.CustomerService;
public class Test {
public static void main(String[] args){
ApplicationContext context=new
ClassPathXmlApplicationContext("com/nareshit/config/myBeans.xml");
CustomerService cs=(CustomerService)context.getBean("customerServiceProxy");
cs.printName();
cs.printURL();
try{
cs.printException();
}catch(Exception e){
System.out.println(e.getMessage());
}
}
}
15
Page
log4j.properties
log4j.rootLogger=info,springapp
log4j.appender.springapp=org.apache.log4j.FileAppender
log4j.appender.springapp.file=springaopexamplelog.html
log4j.appender.springapp.layout=org.apache.log4j.HTMLLayout
log4j.appender.springapp.append=true
Upon execution of the above application, the log file will be generated and the output and
logfile content as shown in the following fig’s will be presented
output
Log file :-
The following diagram helps to understand the above example execution flow.
16
Page
Naresh i Technologies Spring AOP Notes By Mr. Sathish
2. Throws Advice: -
When some kind of exception happens during the execution of a method, then to handle
the exception properly, ThrowsAdvice can be used through the means of
org.springframework.aop.ThrowsAdvice.
Note that this interface is a marker interface meaning that it doesn’t have any method
within it. The method signature inside the Throws Advice can take any of the following
form.
EX:
public class AfterThrowingException implements ThrowsAdvice{
public void afterThrowing(Method method, Object[] args, Object target, Exception exception){
//here afterThrowing method represents the exception raised in the business method.
}
}
For example, in a File Copy program, if some kind of exception happens in the mid-way then
the newly created target file has to be deleted as the partial content in the file doesn’t carry
any sensible meaning. It can be easily achieved through the means of Throws Advice.
DeleteFile.java
17
Page
Naresh i Technologies Spring AOP Notes By Mr. Sathish
AroundAdvice:
The Advice is very different from the other types of the advices because the advice allows us to
perform operations before and after the execution of Joinpoint.This is very useful if we want to
share the state before and after the joinPoint execution in a thread-safe manner like starting
the transactions before the joinpoint execution and ending it after the joinPoint execution .
The spring around advice is compliant with AOP alliance that provides interpretability with
other AOP alliance compliant AOP implementations.
This Advice has to be a SubType of org.aopalliance.intercept.MethodInterceptor interface
In this section we will develop an example to demonstrate how to develop and configure
AroundAdvice.
18
Page
Naresh i Technologies Spring AOP Notes By Mr. Sathish
AccountService.java
package com.nareshit.service;
public interface AccountService {
int withdraw(int accno,double amt);
int deposit(int accno,double amt);
}
AccountServiceImpl.java
package com.nareshit.service;
import com.nareshit.dao.AccountDao;
import com.nareshit.exception.InsufficientFundsException;
import com.nareshit.exception.InvalidAmountException;
public class AccountServiceImpl implements AccountService {
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
AccountDao.java
package com.nareshit.dao;
public interface AccountDao {
int setBalance(int accno,double amt);
double getBalance(int accno);
}
AccountDaoImpl.java
package com.nareshit.dao;
import org.springframework.jdbc.core.JdbcTemplate;
public class AccountDaoImpl implements AccountDao{
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public int setBalance(int accno,double newbalance) {
String sql="update account set bal=? where accountId=?";
int count =jdbcTemplate.update(sql,newbalance,accno);
return count;
}
public double getBalance(int accno) {
String sql="select bal from account where accountId=?";
double balance=jdbcTemplate.queryForObject(sql,Double.class,accno);
return balance;
}
}
InsufficientFundsException.java
package com.nareshit.exception;
public class InsufficientFundsException extends RuntimeException {
public InsufficientFundsException(String msg){
super(msg);
}
}
InvalidAmountException.java
package com.nareshit.exception;
public class InvalidAmountException extends RuntimeException {
public InvalidAmountException(String msg){
super(msg);
}
}
20
Page
AuthorizedManager.java
package com.nareshit.security;
public class AuthorizedManager {
public boolean isAuthorized(String userRole){
boolean flag=false;
if(userRole!=null && userRole.equals("BankAdmin")){
return true;
}
return flag;
}}
MyAroundAdvice.java
package com.nareshit.advices;
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.log4j.Logger;
import com.nareshit.security.AuthorizedManager;
public class MyAroundAdvice implements
MethodInterceptor{
public Object invoke
(MethodInvocation invocation) throws Throwable {
Object target=invocation.getThis();
Method method=invocation.getMethod();
Logger logger=Logger.getLogger(target.getClass().getName());
logger.info("Entered into :"+target.getClass().getName()+" class "+method.getName()+"
method ");
Integer count=0;
try{
AuthorizedManager am=new AuthorizedManager();
boolean flag=am.isAuthorized("BankAdmin");
if(flag==false){
throw new IllegalAccessException(" User is Not Authorised ");
}
count=(Integer) invocation.proceed();
if(count>0){
logger.info(method.getName() +" operation Completed Successfully ");
}
else{
logger.info(method.getName() +" operation Failure...");
}
}catch(Exception exception){
logger.info
("while executing :"+method.getName()+" Exception Occured : "+exception.getMessage());
logger.info(method.getName()+" Operation Failure ");
}
logger.info(method.getName()+ " method Execution completed ");
21
return count;
}
Page
applicationContext.xml
<beans>
<bean id="accountAroundAdvice" class="com.nareshit.advices.MyAroundAdvice">
</bean>
<bean id="accountServiceImpl" class="com.nareshit.service.AccountServiceImpl">
<property name="accountDao" ref="accountDaoImpl"/>
</bean>
<bean id="accountDaoImpl" class="com.nareshit.dao.AccountDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:XE"/>
<property name="username" value="system"/>
<property name="password" value="manager"/>
</bean>
<bean id="accountServiceProxy"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces" value="com.nareshit.service.AccountService"/>
<property name="interceptorNames" value="accountAroundAdvice"/>
<property name="target" ref="accountServiceImpl"/>
</bean>
</beans>
Test.java
package com.nareshit.client;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.nareshit.service.AccountService;
public class Test {
public static void main(String[] args){
ApplicationContext context=new ClassPathXmlApplicationContext
("com/nareshit/config/applicationContext.xml");
AccountService accountService=
(AccountService)context.getBean("accountServiceProxy");
accountService.deposit(3001,6000);
System.out.println("=====================");
accountService.withdraw(3001,4000);
}
}
22
Upon execution of the above application, the log file will be generated logfile content as
Page
Spring defines two types of PointCuts namely the static and the
DynamicPointCuts.
Static point cut verifies whether that join point has to be advised (or) not, only once the result
is catched & reused.
Dynamic pointcut verifies every time as it has to decide the join point based on the argument
passed to method call.
package org.springframework.aop;
The class filter is a special type of object that describes which classes have potential joinpoints
(read methods) on them. The method matcher simply describes which methods for a given
23
NameMatchMethodPointcut :-
Means the pointcut class identifies that method1 of the bean class are eligible for getting
advices. If there is no commonalities in method names we can provide individual method
names by configuring mappedNames property.
mappedNames is the collection type List :-), so we need <list>—-</list> element while
configuring the collection
In this section we will develop an example to demonstrate how to develop and configure
NameMatchMethodPointcut
24
Page
Naresh i Technologies Spring AOP Notes By Mr. Sathish
CustomerService.java
package com.nareshit.bean;
public interface CustomerService {
public String printName();
public String printURL();
public void printException();
}
CustomerServiceImpl.java
package com.nareshit.bean;
public class CustomerServiceImpl implements CustomerService {
private String name;
private String url;
public String printName() {
System.out.println("printName :" + name);
return name;
}
public String printURL() {
System.out.println("printURL :" + url);
return url;
}
public void printException() {
System.out.println("PrintException ");
throw new RuntimeException("Don't sleep in the class room");
}
public void setName(String name) {
this.name = name;
}
public void setUrl(String url) {
this.url = url;
}
}
MyBeforeAdvice.java
package com.nareshit.advices;
import java.lang.reflect.Method;
import org.apache.log4j.Logger;
import org.springframework.aop.MethodBeforeAdvice;
public class MyBeforeAdvice
implements MethodBeforeAdvice {
private Logger logger=Logger.getLogger(MyBeforeAdvice.class);
public void before(Method method, Object[] obj, Object target)throws Throwable {
logger.info("Entered into "+target.getClass().getName()+
" class Method "+method.getName()+" with arguments : "
25
+obj.length);
Page
}}
myBeans.xml
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="customerService" class="com.nareshit.bean.CustomerServiceImpl">
<property name="name" value="sathish"/>
<property name="url" value="www.nareshit.in"/>
</bean>
<bean id="beforeAdvice" class="com.nareshit.advices.MyBeforeAdvice">
</bean>
<!-- <bean id="nameMatchMethodPointcut"
class="org.springframework.aop.support.NameMatchMethodPointcut">
<property name="mappedName" value="printURL"/>
</bean>
<bean id="nameMatchMethodAdvisor"
class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="pointcut" ref="nameMatchMethod"/>
<property name="advice" ref="beforeAdvice"/>
</bean> -->
<bean id="nameMatchMethodAdvisor"
class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<!-- <property name="mappedName" value="printURL"></property> -->
<property name="mappedNames">
<list>
<value>printName</value>
<value>printURL</value>
</list>
</property>
<property name="advice" ref="beforeAdvice"/>
</bean>
<bean id="customerServiceProxy"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="customerService"/>
<property name="proxyInterfaces" value="com.nareshit.bean.CustomerService"/>
<property name="interceptorNames" value=" nameMatchMethodAdvisor "/>
</bean>
</beans>
Test.java
package com.nareshit.client;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.nareshit.bean.CustomerService;
public class Test {
public static void main(String[] args){
ApplicationContext context=new
ClassPathXmlApplicationContext("com/nareshit/xml/myBeans.xml");
CustomerService cs=(CustomerService)context.getBean("customerServiceProxy");
26
cs.printName();
Page
cs.printURL();
try{
cs.printException();
}
catch(Exception e){
}
}
}
RegexpMethodPointcut:-
<bean id=”regexpPointcutAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice" ref="beforeAdvice"/>
<property name="patterns">
<list>
<value>.*Exception.*</value>
<value>.*URL.*</value>
</list> </property>
</bean>
There are many frameworks in the market which allows you to work with AOP programming examples
Spring AOP,AspectJ,JAC(javaAspect Components),Jboss AOP etc...The most populare ones is AspectJ
and Spring AOP.
At the time Spring released AOP, already AspectJ AOP has acceptance in the market, and
seems to be more powerful than Spring AOP,Spring developers instead of comparing the
27
strengths of each framework, they have provided integrations to AspectJ to take the
advantage of it,so spring 2.x not only supports AOP it allows us to work with AspectJ AOP as
Page
well.
Naresh i Technologies Spring AOP Notes By Mr. Sathish
Spring 2.0 also offers support for defining aspects using the new aop
namespace tags. The main problem with programmatic approach is your application code will
tightly couple with Spring,so that you can not detach from spring. If you use declarative
approach,your advice(OR) aspect class are pojo's,you don't need to implement (OR) extend
from any spring specific interface (OR) class.
Your advice classes uses AspectJ AOP classes,in order to declare the pojo as aspect you need to
declare it in the configuration file rather than weaving it using programmatic approach.
The declarative approach also supports all the four types of advices and static pointcut.
In the following section we will explore through the example how to work with various types
of
advices declaratively. To use the aop namespace tags we need to import the spring-aop
schema
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
Within your Spring configurations, all aspect and advisor elements must be placed within an
<aop:config> element (you can have more than one <aop:config> element in an application
context configuration).
An <aop:config> element can contain pointcut, advisor, and aspect elements (note these must
be declared in that order).
Declaring an aspect:-
By using the schema support,an aspect is simply a regular java object defined as a bean in your
spring application context. The state and behaviour is captured in the fields and methods of the
object,and the an aspect is declared using the <aop:aspect> element.
Declaring a pointcut:-
28
beforeAdvice:- before advice runs before a matched method execution.It is declared inside an
<aop:aspect> using the <aop:before>element
After returning advice:- After returning advice runs when a matched method execution
completes normally. It is declared inside an <aop:aspect> using the <aop:after- returning>
element
After advice : After advice runs however a matched method execution exits. It is declared
inside an <aop:aspect> by using the <aop:after> element:
<after-throwing> element.
aroundAdvice:-
Around advice runs "around" a matched method execution. It has the opportunity to do work
both before and after the method executes, and to determine when, how, and even if, the
method actually gets to execute at all. Around advice is often used if you need to share state
before and after a method execution in a thread-safe manner (starting and stopping a timer
for example). Always use the least powerful form of advice that meets your requirements;
don’t use around advice if simple before advice would do. Around advice is declared using the
<aop:around> element. The first parameter of the advice method must be of type
ProceedingJoinPoint. Within the body of the advice, calling proceed() on the
ProceedingJoinPoint causes the underlying method to execute. The proceed method may also
be calling passing in an Object[] - the values in the array will be used as the arguments to the
method execution when it proceeds.
Example:
</aop:aspect>
// start stopwatch
// stop stopwatch
29
return retVal;
Page
Note :-
Spring Aop supports the following aspect pointcut designators for use in pointcut expressions:
execution:- for matching method execution join points
within:- limits matching to join points with in certian types
this:- limits matching to join points(the execution of methods when using spring aop)
target :- limits matching to join points(the execution of methods when using spring aop) when
the target object(application object being proxied) is an instance of given type
Examples:-
the execution of any public method
execution(public * *(..))
execution(* set*(..))
execution(* com.nareshit.CustomerService.*(..))
execution(* com.nareshit.service.*.*(..))
any join point (method execution only in Spring AOP) within the service package:
within(com.nareshit.service.*)
any join point (method execution only in Spring AOP) within the service package or a sub
package:
within(com.nareshit.service..*)
30
Page
Naresh i Technologies Spring AOP Notes By Mr. Sathish
CustomerService.java
package com.nareshit.service;
public interface CustomerService {
String printName();
void printUrl();
void printException();
CustomerServiceImpl.java
package com.nareshit.service;
public class CustomerServiceImpl implements CustomerService{
private String name;
private String url;
}
public String printName() {
System.out.println("Bussiness Method:printName()=>"+name);
return name;
}
public void printUrl() {
System.out.println("Bussiness Method:printUrl()=>"+url);
}
31
Page
LoggingBeforeAdvice.java
package com.nareshit.advices;
import org.aspectj.lang.JoinPoint;
public class LoggingBeforeAdvice {
public void myBefore(JoinPoint joinPoint) {
System.out.println(" Entered into :"+joinPoint.getTarget().getClass().getName()+" class ,
"+joinPoint.getSignature().getName()+" method");
}
}
LoggingAfterAdvice.java
package com.nareshit.advices;
import org.aspectj.lang.JoinPoint;
public class LoggingAfterAdvice {
public void myAfter(JoinPoint joinPoint){
System.out.println(" Execution completed on :"+joinPoint.getTarget().getClass().getName()+"
class , "+joinPoint.getSignature().getName()+" method ");
}
}
applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<bean id="loggingBeforeAdvice"
class="com.nareshit.advices.LoggingBeforeAdvice"/>
<bean id="loggingAfterAdvice"
class="com.nareshit.advices.LoggingAfterAdvice"/>
<bean id="customerService" class="com.nareshit.service.CustomerServiceImpl">
<property name="name" value="sathish"/>
<property name="url" value="www.nareshit.in"/>
</bean>
<aop:config>
<aop:pointcut expression="within(com.nareshit.service.CustomerServiceImpl)"
id="pointcutRef"/>
<aop:aspect ref="loggingBeforeAdvice" >
<aop:before method="myBefore" pointcut-ref="pointcutRef" />
</aop:aspect>
<aop:aspect ref="loggingAfterAdvice">
<aop:after method="myAfter" pointcut-ref="pointcutRef"/>
</aop:aspect>
32
</aop:config>
Page
</beans>
Client.java
package com.nareshit.client;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.nareshit.service.CustomerService;
public class Client {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"com/nareshit/config/applicationContext.xml");
CustomerService service = (CustomerService) ctx
.getBean("customerService");
service.printName();
service.printUrl();
try {
service.printException();
} catch (Exception e) {
System.out.println(e);
}
}}
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
returnValue = joinPoint.proceed();
} catch (Throwable exception) {
logger.info("Exception occured while executing "
+ signatue.getName() + " :: " + exception.getMessage());
}
if (returnValue != null) {
logger.info("Respose of " + signatue.getName() + " method ::"
+ returnValue);
}
33
return returnValue;
}
Page
<aop:config>
<aop:pointcut expression= "within(com.nareshit.service.CustomerServiceImpl)"
id="pointcutRef"/>
<aop:aspect ref="aroundAdvice">
<aop:around method="myAround" pointcut-ref=" pointcutRef "/>
</aop:aspect>
</aop:config>
annotate the classes with annotations.In order to make as class aspect,we need to annotate
the
class with @Aspect. To expose a method as advice method,we need to annotate the method in
aspect class @Around,(OR) @Before (OR) @AfterReturnining (OR)@AfterThrowing
representing the type of advice.
Note :- In order to detect the annotations marked on the classes ,we need to add
CustomerService.java
package com.nareshit.service;
public interface CustomerService {
String displayName();
String printUrl();
void printException();
34
}
Page
Naresh i Technologies Spring AOP Notes By Mr. Sathish
CustomerServiceImpl.java
package com.nareshit.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service("customerService")
public class CustomerServiceImpl implements CustomerService{
@Value("sathish")
private String name;
@Value("www.nareshit.in")
private String url;
public void printException() {
System.out.println("Bussiness Method:printException()");
throw new RuntimeException("Custom Exception");
}
public String displayName() {
System.out.println("Bussiness Method:displayName()=>"+name);
return name;
}
public String printUrl() {
System.out.println("Bussiness Method:printUrl()=>"+url);
return url;
}
}
Advices.java
package com.nareshit.service;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Service;
@Service("advices")
@Aspect
public class Advices {
private static Logger logger=Logger.getLogger(Advices.class);
@Before("within(com.nareshit.service.CustomerServiceImpl)")
public void myBefore(JoinPoint joinPoint){
logger.info("Entered into "+joinPoint.getTarget().getClass().getName()+" class " );
logger.info
("Method :"+joinPoint.getSignature().getName());
}
35
@AfterReturning(pointcut="execution(* print*(..))",
Page
returning="result")
applicationContext.xml
}catch(Exception e){
Page
}
}
Spring –Transaction:
What does transaction means?
A transaction is a logical unit of work that contains one or more SQL statements. A transaction
is an atomic unit. The effects of all the SQL statements in a transaction can be either all
committed (applied to the database) or all rolled back (undone from the database). To
illustrate the concept of a transaction, consider a banking database. When a bank customer
transfers money from a savings account to a current account, the transaction can consist of
three separate operations:
Your application must allow for two situations. If all three SQL statements can be performed to
maintain the accounts in proper balance, the effects of the transaction can be applied to the
database. However, if a problem such as insufficient funds, invalid account number, or a
hardware failure prevents one or two of the statements in the transaction from completing,
the entire transaction must be rolled back so that the balance of all accounts is correct.
Consistency:- Consistency states that only valid data will be written to the database.
Isolation :- requires that multiple transactions occurring at the same time not impact each
other’s execution.
Durability:-Ensures that any transaction committed to the database will not be lost. Durability
is ensured through the use of database backups and transaction logs that facilitate the
restoration of committed transactions in spite of any subsequent software or hardware
failures.
Note :
Like EJB Spring supports both programmatic and declarative transaction management support.
But Spring’s transaction support is different from EJB. EJB uses JTA (Java Transaction Support)
implementation. But Spring uses transaction support offered by the persistent mechanism such
as JDBC, Hibernate, JDO, third party JTA implementation for distributed (XA) transaction.
37
Spring does not directly manage transactions. Instead, it comes with a selection of transaction
Page
transaction implementation provided by either JTA or the persistence mechanism. You need to
choose the correct transaction manager as per your design.
orm.hibernate.HibernateTransactionManager Hibernate 2
orm.hibernate3.HibernateTransactionManager Hibernate 3
orm.jpa.JpaTransactionManager JPA
With programmatic transaction management developers work with the Spring transaction
abstraction, which can run over any underlying transaction infrastructure. Programmatic
transactions are good when you want complete control over transactional boundaries.
Programmatic transaction management is usually a good idea only if you have a small number
of transactional operations. For example, if you have a web application that require
transactions only for certain update operations, you may not want to set up transactional
proxies using Spring or any other technology. Using programmatic transaction may be a good
approach.
Spring has several built-in implementations of this interface for use with different
transaction management APIs:
BookShopDAO.java
package com.nareshit.dao;
39
}
Naresh i Technologies Spring AOP Notes By Mr. Sathish
BookShopDAOImpl.java
package com.nareshit.dao;
import org.apache.log4j.Logger;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
public class BookShopDAOImpl extends JdbcDaoSupport implements BookShopDAO {
private static Logger logger=Logger.getLogger(BookShopDAOImpl.class);
private PlatformTransactionManager transactionManager;
private static final String SQL_TO_GET_BOOK_PRICE="select price from Book where ISBN=?";
private static final String SQL_DEDUCT_BALANCE="UPDATE ACCOUNT SET BAL = BAL - ? WHERE accountId = ?";
private static final String SQL_UPDATE_BOOK_STOCK="UPDATE BOOK_STOCK SET STOCK = STOCK - ? WHERE ISBN
= ?";
public void purchase(final String isbn,final int accountId,final int noOfBooks) {
double totalPrice=noOfBooks*price;
getJdbcTemplate().update(SQL_DEDUCT_BALANCE,totalPrice,accountId);
getJdbcTemplate().update(SQL_UPDATE_BOOK_STOCK,noOfBooks,isbn);
transactionManager.commit(transaction);
}
catch(Exception exception){
transactionManager.rollback(transaction);
logger.error("Exception Occured while purchaing the Book ::"+exception.getMessage());
}
}
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
}
applicationContext.xml
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
40
Main.java
package com.nareshit.client;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.nareshit.dao.BookShopDAO;
public class Main {
public static void main(String[] args) {
ApplicationContext ctx=
new
ClassPathXmlApplicationContext("com/nareshit/config/applicationContext.xml");
BookShopDAO bookShopDao=(BookShopDAO)ctx.getBean("bookShopDao");
bookShopDao.purchase("AJN102",3001,3);
}
}
In the above Example code we have used Platform Transaction Manager for performing
programmatic mode of transaction management. The Platform Transaction Manager is the
core API in Spring framework for transaction management. This class completely shields the
internals of Transaction management so that the application can concentrate only on the
business logic. The PlatformTransactionManager class is also wrapped with the DataSource that
connects to the database. Closely related objects with the PlatformTransactionManager are
TransactionDefinition and TransactionStatus objects.
The TransactionDefinition object encapsulates the transactional properties such as the isolation
level, propagation behavior, timeout etc. The TransactionStatus object represents the
transaction whether it is in New Transaction (OR) not. In the beginning of the method, we
acquire a TransactionStatus object from the TransactionDefinition object. In the case of
successful scenario, the transaction is commited on the TransactionStatus object, whereas in
the case of failure, the transaction is made to roll-back.
Declarative - Transaction Management
In a Declarative TransactionManagement approach,the developers will declare the
transactional semantics in a configuration file rather than programming it using code.
The main advantage with this is instead of writing logic to manage ,your classes are free from
Transaction releated logic and if you want switch (OR) Don’t want to use Transactions you
don’t need to modify your logic.
41
In Order to manage the transactions we need to declare an Transactional Advice which will
manages the transactions(commit and rollback’s ) logic. In Order to configure an Transactional
advice we need to use <tx:advice> tag.
BookShopDAO.java
package com.nareshit.dao;
public interface BookShopDAO {
public void purchase( String isbn,int accountId,int noOfBooks);
BookShopDAOImpl.java
package com.nareshit.dao;
import java.io.IOException;
import org.apache.log4j.Logger;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.transaction.annotation.Transactional;
public class BookShopDAOImpl extends JdbcDaoSupport implements BookShopDAO {
private static Logger logger=Logger.getLogger(BookShopDAOImpl.class);
private static final String SQL_TO_GET_BOOK_PRICE="select price from Book where ISBN=?";
private static final String SQL_DEDUCT_BALANCE="UPDATE ACCOUNT SET BAL = BAL - ? " +
"WHERE accountId = ?";
private static final String SQL_UPDATE_BOOK_STOCK="UPDATE BOOK_STOCK SET STOCK
=STOCK - ? WHERE ISBN = ?";
double
price=getJdbcTemplate().queryForObject(SQL_TO_GET_BOOK_PRICE,Double.class,isbn);
Page
double totalPrice=noOfBooks*price;
Naresh i Technologies Spring AOP Notes By Mr. Sathish
int
balanceUpdateCount=getJdbcTemplate().update(SQL_DEDUCT_BALANCE,totalPrice,accounted)
;
int
stockUpdateCount=getJdbcTemplate().update(SQL_UPDATE_BOOK_STOCK,noOfBooks,isbn);
applicationContext.xml
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:XE"/>
<property name="username" value="system"/>
<property name="password" value="manager"/>
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="bookShopDao"
class="com.nareshit.dao.BookShopDAOImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
</aop:config>
</beans>
Page
Main.java
package com.nareshit.client;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.nareshit.dao.BookShopDAO;
public class Main {
public static void main(String[] args) {
ApplicationContext ctx= new
ClassPathXmlApplicationContext("com/nareshit/config/applicationContext.xml");
BookShopDAO bookShopDao=(BookShopDAO)ctx.getBean("bookShopDao");
bookShopDao.purchase("AJN102",3001,3);
}
}
In this instead of declaraing the transaction semantics in the declaration file we will directly
annotate the class methods with @Transactional annotation. You can specify the readOny and
propagation attributes in it.
In the previous example instead of declaring the Transactional semantics in the
declaration,you can directly mark the purchase method with @Transactional annotation.
@Transactional
public void purchase(final String isbn,final int accountId,final int noOfBooks) {
logger.info("Enterted into purchase of BookShopDAOImpl ");
double
price=getJdbcTemplate().queryForObject(SQL_TO_GET_BOOK_PRICE,Double.class,isbn);
double totalPrice=noOfBooks*price;
int
balanceUpdateCount=getJdbcTemplate().update(SQL_DEDUCT_BALANCE,totalPrice,accountId);
int
stockUpdateCount=getJdbcTemplate().update(SQL_UPDATE_BOOK_STOCK,noOfBooks,isbn);
In Order to detect your annotations that has been marked,you need to declare a tag in Spring
beans configuration file as
<tx:annotation-driven transaction-manager=”transactionManager”/>
44
Page