Spring AOP

@Aspect Annotation in Spring

@AspectJ refers to a style of declaring aspects as regular Java classes annotated with Java 5 annotations. The @AspectJ style was introduced by the AspectJ project as part of the AspectJ 5 release. Spring 2.0 interprets the same annotations as AspectJ 5, using a library supplied by AspectJ for pointcut parsing and matching. The AOP runtime is still pure Spring AOP though, and there is no dependency on the AspectJ compiler or weaver.

The @AspectJ support is enabled by including the following element inside your spring configuration:

<aop:aspectj-autoproxy/>

You also need to add following libraries on class path

  • aspectjrt.jar
  • aspectjweaver.jar
  • aspectj.jar


Declaring an aspect

With the @AspectJ support enabled, any bean defined in your application context with a class that is an @AspectJ aspect (has the @Aspect annotation) will be automatically detected by Spring and used to configure Spring AOP. The following example shows the minimal definition required for a logging aspect:

package com.dineshonjava.sdnext.aop.aspect;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class LoggingAspect
{
 //....
}

They will be configured in XML like any other bean as follows:

<bean class="com.dineshonjava.sdnext.aop.aspect.LoggingAspect" id="logAspect">
 <!-- configure properties of aspect here as normal -->
</bean>


Declaring a pointcut

Spring AOP only supports method execution join points for Spring beans, so you can think of a pointcut as matching the execution of methods on Spring beans.
A pointcut helps in determining the join points (ie methods) of interest to be executed with different advices. While working with @AspectJ based configuration, pointcut declaration has two parts:

  • A pointcut expression that determines exactly which method executions we are interested in.
  • A pointcut signature comprising a name and any number of parameters. The actual body of the method is irrelevant and in fact should be empty.
package com.dineshonjava.sdnext.aop.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class LoggingAspect
{
   @Pointcut("execution(* com.dineshonjava.sdnext.aop.emp.Employee.addEmployee(..))")
   public void addEmployee(){}
}

The following example defines a pointcut named ‘businessService’ that will match the execution of every method available in the classes under the package com.dineshonjava.sdnext.aop.aspect.service:

import org.aspectj.lang.annotation.Pointcut;

@Pointcut("execution(* com.dineshonjava.sdnext.aop.aspect.service.*.*(..))") // expression 
private void businessService() {}  // signature

Combining pointcut expressions

Pointcut expressions can be combined using ‘&&’, ‘||’ and ‘!’. It is also possible to refer to pointcut expressions by name. The following example shows three pointcut expressions: anyPublicOperation (which matches if a method execution join point represents the execution of any public method); inTrading (which matches if a method execution is in the trading module), and tradingOperation (which matches if a method execution represents any public method in the trading module).

@Pointcut("execution(public * *(..))")
    private void anyPublicOperation() {}
    
    @Pointcut("within(com.dineshonjava.sdnext.aop.aspect.trading..*)")
    private void inTrading() {}
    
    @Pointcut("anyPublicOperation() && inTrading()")
    private void tradingOperation() {}

Sharing common pointcut definitions

When working with enterprise applications, you often want to refer to modules of the application and particular sets of operations from within several aspects. We recommend defining a “SystemArchitecture” aspect that captures common pointcut expressions for this purpose. A typical such aspect would look as follows:

package com.dineshonjava.sdnext.aop.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class SystemArchitecture {

  /**
   * A join point is in the web layer if the method is defined
   * in a type in the com.dineshonjava.sdnext.aop.aspect.web package or any sub-package
   * under that.
   */
  @Pointcut("within(com.dineshonjava.sdnext.aop.aspect.web..*)")
  public void inWebLayer() {}

  /**
   * A join point is in the service layer if the method is defined
   * in a type in the com.dineshonjava.sdnext.aop.aspect.service package or any sub-package
   * under that.
   */
  @Pointcut("within(com.dineshonjava.sdnext.aop.aspect.service..*)")
  public void inServiceLayer() {}

  /**
   * A join point is in the data access layer if the method is defined
   * in a type in the com.dineshonjava.sdnext.aop.aspect.dao package or any sub-package
   * under that.
   */
  @Pointcut("within(com.dineshonjava.sdnext.aop.aspect.dao..*)")
  public void inDataAccessLayer() {}

  /**
   * A business service is the execution of any method defined on a service
   * interface. This definition assumes that interfaces are placed in the
   * "service" package, and that implementation types are in sub-packages.
   * 
   * If you group service interfaces by functional area (for example, 
   * in packages com.dineshonjava.sdnext.aop.aspect.abc.service and   com.dineshonjava.sdnext.aop.aspect.def.service) then
   * the pointcut expression "execution(* com.dineshonjava.sdnext.aop.aspect..service.*.*(..))"
   * could be used instead.
   *
   * Alternatively, you can write the expression using the 'bean'
   * PCD, like so "bean(*Service)". (This assumes that you have
   * named your Spring service beans in a consistent fashion.)
   */
  @Pointcut("execution(* com.dineshonjava.sdnext.aop.aspect.service.*.*(..))")
  public void businessService() {}
  
  /**
   * A data access operation is the execution of any method defined on a 
   * dao interface. This definition assumes that interfaces are placed in the
   * "dao" package, and that implementation types are in sub-packages.
   */
  @Pointcut("execution(* com.dineshonjava.sdnext.aop.aspect.dao.*.*(..))")
  public void dataAccessOperation() {}

}

The pointcuts defined in such an aspect can be referred to anywhere that you need a pointcut expression. For example, to make the service layer transactional, you could write:

<aop:config>
  <aop:advisor advice-ref="tx-advice" pointcut="com.dineshonjava.sdnext.aop.aspect.SystemArchitecture.businessService()">
</aop:advisor></aop:config>

<tx:advice id="tx-advice">
  <tx:attributes>
    <tx:method name="*" propagation="REQUIRED">
  </tx:method></tx:attributes>
</tx:advice>


Declaring advices

You can declare any of the five advices using @{ADVICE-NAME} annotations as given below.

  1. @Before – Run before the method execution
  2. @After – Run after the method returned a result
  3. @AfterReturning – Run after the method returned a result, intercept the returned result as well.
  4. @AfterThrowing – Run after the method throws an exception
  5. @Around – Run around the method execution, combine all three advices above.
@Before("businessService()")
public void doBeforeTask(){
 ...
}

@After("businessService()")
public void doAfterTask(){
 ...
}

@AfterReturning(pointcut = "businessService()", returning="retVal")
public void doAfterReturnningTask(Object retVal){
  // you can intercept retVal here.
  ...
}

@AfterThrowing(pointcut = "businessService()", throwing="ex")
public void doAfterThrowingTask(Exception ex){
  // you can intercept thrown exception here.
  ...
}

@Around("businessService()")
public void doAroundTask(){
 ...
}

You can define you pointcut inline for any of the advices. Below is an example to define inline pointcut for before advice:

@Before("execution(* com.dineshonjava.sdnext.aop.aspect.service.*.*(..))")
public doBeforeTask(){
 ...
}

<

Previous
Next
Dinesh Rajput

Dinesh Rajput is the chief editor of a website Dineshonjava, a technical blog dedicated to the Spring and Java technologies. It has a series of articles related to Java technologies. Dinesh has been a Spring enthusiast since 2008 and is a Pivotal Certified Spring Professional, an author of a book Spring 5 Design Pattern, and a blogger. He has more than 10 years of experience with different aspects of Spring and Java design and development. His core expertise lies in the latest version of Spring Framework, Spring Boot, Spring Security, creating REST APIs, Microservice Architecture, Reactive Pattern, Spring AOP, Design Patterns, Struts, Hibernate, Web Services, Spring Batch, Cassandra, MongoDB, and Web Application Design and Architecture. He is currently working as a technology manager at a leading product and web development company. He worked as a developer and tech lead at the Bennett, Coleman & Co. Ltd and was the first developer in his previous company, Paytm. Dinesh is passionate about the latest Java technologies and loves to write technical blogs related to it. He is a very active member of the Java and Spring community on different forums. When it comes to the Spring Framework and Java, Dinesh tops the list!

Share
Published by
Dinesh Rajput

Recent Posts

Strategy Design Patterns using Lambda

Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…

2 years ago

Decorator Pattern using Lambda

Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…

2 years ago

Delegating pattern using lambda

Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…

2 years ago

Spring Vs Django- Know The Difference Between The Two

Technology has emerged a lot in the last decade, and now we have artificial intelligence;…

2 years ago

TOP 20 MongoDB INTERVIEW QUESTIONS 2022

Managing a database is becoming increasingly complex now due to the vast amount of data…

2 years ago

Scheduler @Scheduled Annotation Spring Boot

Overview In this article, we will explore Spring Scheduler how we could use it by…

3 years ago