Spring Aspect cheatsheet
Put some easy-to-use spring aspect syntax manuals.
use
Full code: spring-aop
- import library, reference build.gradle
- Aspects are marked with @Aspect and @Configuration. refer to LogingAspect
Why?
Just like the btrace manual written before, in order to facilitate the search and actual operation, I would like to share some cheatsheet s related to writing Aspect.
concept
- Aspect
As a modular set of concerns, cross-sections in many classes. For example, transaction management @Transactional is a cross-section related to transactions in enterprise applications. Or an aspect for logging. Typically a section will contain a complete
meaningful collection of . Generally, Pointcut definitions and Advice definitions are included. - Join Point
Represents a point of program execution. Represents the execution point of a method in spring. - Advice
At a particular Join Point, the operation taken by Aspect. Contains different types (around, before, after). Many aop frameworks include
spring implements Advice with interceptors, and maintains an interceptor chain to handle multiple Advices of a JointPoint. - Pointcut
Define method aspects that satisfy some defined conditions. Advice will be executed on all JoinPoint s that satisfy the Pointcut. For example, Pointcut can be defined as
Execute (within(com.example.controller.*)) on all Controller methods. This article will also provide more examples for easy search. - Introduction
Add new methods or properties on a class basis. For example, a property IsModified can be introduced for some bean s to facilitate caching. - Target object
A class object (also called an advised object) waiting to be enhanced by an aspect. Because spring is implemented by proxy, this is also called the proxy object. - AOP proxy
`
In order to implement aspect, the enhanced object implemented by JDK dynamic proxy, or cglib proxy. - Weaving
The process of combining multiple aspects and real applications can be implemented at compile time (aspectj compiler), load time, and runtime (spring aop).
Advice type
- Before
- AfterReturning
- AfterThrowing
- Around
around advice will have a ProceedingJoinPoint parameter. This is the strongest type of advice. It provides the proceed method to
Call the original logic. Several other Advie s are similar to the read-only type, and only provide a parameter of the JoinPoint type.
Common examples of PointCut
example | explain |
---|---|
within(com.xyz.service.*) | Implement methods of all classes of com.xyz.service (excluding subpackages) |
within(com.xyz.service..*) | Implement methods of all classes of com.xyz.service (including subpackages) |
this(com.xyz.service.AccountService) | Execute the class that implements the interface of AccountService |
execution(* com.example.springaop.controller.*.*(..)) | implement |
execution(public * *(..)) | Execute all public methods |
execution(* set*(..)) | Execute all methods whose method name starts with set |
execution(* com.xyz.service.AccountService.*(..)) | Executes all methods in the com.xyz.service.AccountService class. |
execution(* com.xyz.service.*.*(..)) | Execute all methods in com.xyz.service (excluding subpackages) |
execution(* com.xyz.service..*.*(..)) | Execute all methods in com.xyz.service (including subpackages) |
@within(org.springframework.transaction.annotation.Transactional) | A class has @Transactional annotation |
@annotation(org.springframework.transaction.annotation.Transactional) | A method has @Transactional annotation |
Concrete syntax:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)
Advice usage example
- Before
Before the method starts to execute, you can use JoinPoint to get the status of the currently executing method. This parameter can be obtained for the subsequent several.
@Before("execution(* com.xyz.myapp.dao.*.*(..))") public void doAccessCheck(JoinPoint jp) { }
-
AfterReturning
After returning normally:@AfterReturning( pointcut="com.xyz.myapp.CommonPointcuts.dataAccessOperation()", returning="retVal") public void doAccessCheck(Object retVal) { // ... }
-
AfterThrowing
After throwing an exception:@AfterThrowing( pointcut="com.xyz.myapp.CommonPointcuts.dataAccessOperation()", throwing="ex") public void doRecoveryActions(DataAccessException ex) { // ... }
-
Arround
Around advice can use ProceedingJoinPoint.proceed to call the original implementation.
@Around("com.xyz.myapp.CommonPointcuts.businessService()") public Object timing(ProceedingJoinPoint jp) throws Throwable { // start stopwatch Object retVal = jp.proceed(); // stop stopwatch return retVal; }
- Pass parameters to Advice.
In addition to the parameters that can be obtained by the above JoinPoint, you can also obtain them in the following ways:
@Before("com.xyz.myapp.CommonPointcuts.dataAccessOperation() && args(account,..)") public void validateAccount(Account account) { // ... }
account is the first parameter in the above example. Of course, the PointCut specified by dataAccessOperation must have at least one parameter.
- Order of Advice
Execute in the following order:
@Around, @Before, @After, @AfterReturning, @AfterThrowing
Different Aspect s can also specify the order through @Order
a complete example
Example for counting elapsed time and logging requests:
package com.example.springaop; import org.aspectj.lang.*; import org.aspectj.lang.annotation.*; import org.springframework.context.annotation.*; import java.util.*; @Configuration @Aspect public class LogingAspect { @Pointcut("within(com.example.springaop.controller.*)") public void ctrlMethod() { } @Pointcut("execution(public * *(..)) ") public void publicMethod() {} @Around("ctrlMethod() && publicMethod()") public Object loggingAndTiming(ProceedingJoinPoint jp) throws Throwable { long t1 = System.currentTimeMillis(); String className = jp.getSignature().getDeclaringTypeName(); String methodName = jp.getSignature().getName(); String args = Arrays.toString(jp.getArgs()); try { return jp.proceed(); } catch (Throwable e) { throw e; } finally { System.out.println(String.format("%s.%s with args: %s , cost time: %d", className, methodName, args, System.currentTimeMillis() - t1)); } } }