This is the 26th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

Spring AOP’s @AspectJ annotation

New features released since Spring2.0:

  • @aspectJ annotations to poJOs to define aspects and Advice.
  • Simplification of XML configuration, introducing aOP-specific namespace approach to configuring AOP.

Spring searches for classes annotated with @AspectJ and weaves them into the system.

use

Define an Aspect as follows:

@Aspect
public class PerformanceTraceAspect {
    private final Log logger = LogFactory.getLog(PerformanceTraceAspect.class);

    @Pointcut("execution(public void *.method1()) || execution(public void *.method2())")
    public void pt(a) {}

    @Around("pt()")
    public Object performanceTrace(ProceedingJoinPoint joinPoint) throws Throwable {
        StopWatch watch = new StopWatch();
        try {
            watch.start();
            return joinPoint.proceed();
        } finally {
            watch.stop();
            if (logger.isInfoEnabled()) {
                logger.info("PT in method[" + joinPoint.getSignature().getName() + "] > > >"+ watch.toString()); }}}}Copy the code

How do we weave this Aspect into our target object? There are two ways:

Programming weaving mode

Using AspectJProxyFactory:

AspectJProxyFactory weaver = new AspectJProxyFactory();
weaver.setProxyTargetClass(true);
weaver.setTarget(new Foo());
weaver.addAspect(PerformanceTraceAspect.class); // Add the section
Object proxy = weaver.getProxy();
Copy the code
Automatic proxy weaving mode

Using AutoProxyCreator: AnnotationAwareAspectJAutoProxyCreator. It automatically collects aspects registered in the IOC container and applies them to target objects.

Only need to inject AnnotationAwareAspectJAutoProxyCreator in the configuration file, spring2. After x provides a simple configuration:

<aop:aspectj-autoproxy proxy-target-clas="true">
</aop:aspectj-autoproxy>
Copy the code

Pointcut in the form of @aspectj

@Pointcut("execution(public void *.method1()) || execution(public void *.method2())")
public void pt(a) {}
Copy the code

SpringAOP integrates only parts of AspectJ’s Pointcut, including language support for Pointcut.

The @aspect pointcut declaration consists of two main parts:

  • Pointcut Expression
    • Where the Pointcut is actually specified.
    • Expressions can && | |! These logical operators
  • Pointcut Signature
    • A defined method is required as a carrier, which must be of type void
    • If the method is public, the pointcut can be referenced by other aspects; if private, it can only be referenced by the current Aspect class.

Aspectj’s Pointcut representation language has many identifiers, but SpringAOP can only use a few because Spring only applies method-level Pointcuts.

  • execution
    • Prescribed format:Execution (< modifier pattern >? < return type mode >< method name mode >(< parameter mode >)< exception mode >?
    • Only return type, method name, and parameter pattern are required, others can be omitted.
    • There are two wildcards we can use here
      • *Match any meaning
      • .All classes in the current package and its subpackages
  • within
    • Accepts only type declarations that match all JointPoints of the specified type. For SpringAOP, match all the methods below this class.
  • This and target
    • This refers to the method caller and target refers to the called.
    • This (o1) && this(o2) is matched only when o1 objects call methods of o2 objects.
  • args
    • Specifies the type of the argument that will be caught when the argument type matches the calling method.
  • @within
    • Specify some annotations. If a class has a specified annotation, all methods in that class will be matched.
  • @target
    • The target class is matched when the annotation is specified. SpringAOP is no different from @within, except that @within is static matching and @target is runtime dynamic matching.
  • @args
    • If the type of the passed parameter has the specified annotation type, it is matched.
  • @annotation
    • All object class methods in the system that annotate the specified annotation will be matched.

These annotated Pointcuts are eventually translated into concrete Pointcut objects within Spring.

Advice in the form of @aspectj

Mainly some Advice notes:

  • @Before
    • To obtain the parameters of a method, there are two ways
      • The first parameter is set to JoinPoint. This parameter must be in the first place and can be used for all Advice except Around Advice and Introduction.
      • Args identifier binding (not commonly used)
  • @AfterReturning
    • The return value of a method can be retrieved from a unique attribute called RETURNING.
  • @AfterThrowing
    • It has a unique property: Throwing accepts exception objects thrown.
  • @after (also called finally)
    • Generally do the release of resources
  • @Around
    • Its first parameter must be of type ProceedingJoinPoint and must be specified. The ProceedingJoinPoint’s proceed() method performs the call to the original method.
    • The proceed() method, which requires arguments, passes an Object[] array.
  • @DeclareParents
    • Dealing with Introduction, not much description.

other

Order of execution of advice
  • If the advice is in an aspect class:

The same advice is prioritized in the claim order, but BeforeAdvice has a higher claim priority, it is executed first. AfterReturningAdvice is to declare the highest priority first, but execute the highest priority later.

before1
before2
task
after returning 2
after returning 1
Copy the code
  • If the Advice is in different aspects:

With the Ordered interface, otherwise the order of Advice execution cannot be determined.

The instantiation pattern of an Aspect

There are three types: singleton, perthis, and pertarget. (Less important)