Aspect Oriented Programming(AOP) with Spring
Aspects Oriented programming(AOP) is another way of programming in Spring. Instead of Object oriented programming, in which the key unit is class , in AOP the key unit is aspect.
AOP framework is part of the Spring and comes bundled with it. No additional installation is required. Spring AOP is implemented in pure Java and can be used in a web container or enterprise server. Before we move ahead with an example , let us look at some terminologies which we will be using in this application
- Aspect: a modularization of a concern that cuts across multiple classes. Transaction management is a good example of a crosscutting concern in Java EE applications.
- Join point: a point during the execution of a program, such as the execution of a method or the handling of an exception. In Spring AOP, a join point always represents a method execution.
- Advice: action taken by an aspect at a particular join point. Different types of advice include “around,” “before” and “after” advice. (Advice types are discussed below.) Many AOP frameworks, including Spring, model an advice as an interceptor, maintaining a chain of interceptors around the join point.
- Pointcut: a predicate that matches join points. Advice is associated with a pointcut expression and runs at any join point matched by the pointcut (for example, the execution of a method with a certain name). The concept of join points as matched by pointcut expressions is central to AOP, and Spring uses the AspectJ pointcut expression language by default.
Now let us see what is really an aspect and how it can be useful in an application. This is a simple application to demonstrate how a cross cutting concern is being invoked.
Assume that in an application you have to check the status of user before every save. The user can be updated by various services and it is important to verify the user whose details are being updated is valid any more or not. It might happen that some one else has updated the state of user while you are trying to save the records. I know you might want to do this by using hibernate but here we are concerned with the sate of object and not its version.
In your application-Context.xml , you will define the aspect and the pointcut as
<?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” xmlns:aop=”http://www.springframework.org/schema/aop”
xmlns:context=”http://www.springframework.org/schema/context” xmlns:jee=”http://www.springframework.org/schema/jee”
xmlns:tx=”http://www.springframework.org/schema/tx”
xsi:schemaLocation=”
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd”><context:property-placeholder location=”classpath:component.properties”/>
<!– Connection Pool –>
<bean id=”dataSource” destroy-method=”close”>
<property name=”driverClass” value=”${jdbc.driverClass}”/>
<property name=”jdbcUrl” value=”${jdbc.url}”/>
<property name=”user” value=”${jdbc.username}”/>
<property name=”password” value=”${jdbc.password}”/>
</bean><!– JPA EntityManagerFactory –>
<bean id=”entityManagerFactory”
p:dataSource-ref=”dataSource”>
<property name=”jpaVendorAdapter”>
<bean>
<property name=”database” value=”${jpa.database}”/>
<property name=”showSql” value=”${jpa.showSql}”/>
</bean>
</property>
</bean><!– Transaction manager for a single JPA EntityManagerFactory (alternative to JTA) –>
<bean id=”transactionManager”
p:entityManagerFactory-ref=”entityManagerFactory”/><!– Activates various annotations to be detected in bean classes for eg @Autowired–>
<context:annotation-config/><!– enable the configuration of transactional behavior based on annotations –>
<tx:annotation-driven transaction-manager=”transactionManager”/><!– Property Configurator –>
<bean id=”propertyConfigurer”>
<property name=”location” value=”jdbc.properties”/>
</bean><context:component-scan base-package=”cs.comp.dao”/>
<bean id=”geekTransactionService”/>
<bean id=”validationService”/>
<aop:config>
<aop:aspect id=”geekServiceAspect” ref=”validationService”>
<aop:pointcut id=”geekServicePointCut”
expression=”execution(* cs.comp.service.GeekTransactionService.addRecords*(..))” />
<aop:before
pointcut-ref=”geekServicePointCut”
method=”isValid”/>
</aop:aspect>
</aop:config></beans>
Make Sure you have aspectjweaver.jar and aspectjrt.jar in your classpath along with other jar files.
Here is the service class GeekTransactionServiceImpl
public class GeekTransactionServiceImpl implements GeekTransactionService {
/** DAO variable */
@Autowired
GeekUserDAO geekUserDAO;
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
public void addRecords(){
try {
//do some processing and save to dbase.
System.out.println( ” Saving records “);
} catch (Exception e) {
e.printStackTrace();
log.fatal(
“Problem in updating records “, e);
}
}
ValidationService Interface
public interface ValidationService {
public boolean isValid() throws Exception ;
}
ValidationServiceImpl Class
public class ValidationServiceImpl {
public boolean isValid() throws Exception{
boolean isValid = false ;
System.out.println( ” Hitting AOP Point cut “);
return isValid;
}
}
And this is the class to run the code
public class TestService {
public static void main(String args[]){
GeekTransactionService geekTransactionService ;
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] {
“applicationContext.xml” });
geekTransactionService = (GeekTransactionService) appContext.getBean(“geekTransactionService”);
geekTransactionService.addRecords();
}
}
When you run the TestService class , you will see the output
Hitting AOP Point cut
Saving records
Now let us understand how this works. Look at the definition below in applicationContext.xml
<bean id=“geekTransactionService” class=“cs.comp.service.GeekTransactionServiceImpl”/>
<bean id=“validationService” class=“cs.comp.aop.ValidationServiceImpl”/>
<aop:config>
<aop:aspect id=“geekServiceAspect” ref=“validationService”>
<aop:pointcut id=“geekServicePointCut”
expression=“execution(* cs.comp.service.GeekTransactionService.addRecords*(..))” />
<aop:before
pointcut-ref=“geekServicePointCut”
method=“isValid”/>
</aop:aspect>
</aop:config>
</beans>
The geekservicePointCut states that whenever any method of geekTransaction service which starts with addRecords and with any number of parameters is invoked, invoke the isValid method of the PointCut.
Lte us assume there is another method addrecordsForXYZ in GeekService and is called this way
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
public void addRecords(){
try {
//do some processing and save to dbase.
System.out.println( ” Saving records “);
} catch (Exception e) {
e.printStackTrace();
log.fatal(
“Problem in updating records “, e);
}
addRecordsXYZ();
}
Since aspect would be invoked whenever there is call addRecord*.(–) method , do you think aspect will be invoked ?
Would like to know your response.


Spring’ AOP is complcated, why use AOP? AOP must be for Domain-Driven Design, refer another light-weight DDD + AOP framework : JdonFramework(https://jdon.dev.java.net/)
@bqlr Spring AOP is complicated for first time users. In the example above I have explained how to start using it easily and effectively.
With another framework there is learning curve and integration with existing framework
Hi, thanx for the article. But i have tried getting spring AOP to work without much success. I dont get any error message. For both schema based definitions and annotations. Not getting errror messages is the most annoying.
@Adedayo
If the configuration files are not correct , an error message will be thrown. I had seen happening in my case.So if you do not see error message , your settings are correct. What is not working , the method calls ?
Does the above code work for you ?
Hello Vinay,
I have a question about the ClassPathXmlApplicationContext(new String[] {
“applicationContext.xml” }):
If i am using a test class in the test packages that loads the application context (stored in web/WEB-INF/) what path should i have to write? Because with your configuration it doesn’t find the file applicationContext.xml.
Thanks
(i wrote a more detailed explanation at http://stackoverflow.com/questions/1009357/spring-context-tests-cant-find-config-locations/2021404#2021404)
@matteo I am running this as standalone java application not as web application.My applicationContext.xml is in src(or root) folder
Here is the package structure
project
cs
other java files
classes
META-INF
applicationContext.xml
log4j.properties
Hope this makes it clear.
thanks Vinay, it think it’s still similar to what i am trying to do, since i want to run some unit tests of some simple beans and their dependencies. Anyway, i think i am on the way to solve the problem.