头图

Introduction to Spring AOP

1. Definition

AOP is Aspect Oriented Programming, that is, aspect-oriented programming.

So what is AOP?

Let’s review OOP: Object Oriented Programming. As a model of object-oriented programming, OOP has achieved great success. The main functions of OOP are data encapsulation, inheritance, and polymorphism.

AOP is a new programming method, which is different from OOP. OOP regards the system as the interaction of multiple objects, and AOP decomposes the system into different concerns, or called aspects.

AOP is mainly used to solve some system-level problems in program development, such as logs, transactions, and permission waiting. The interceptor design of Struts2 is based on the idea of AOP, which is a classic example.

2. AOP principle

The problem that AOP needs to solve is how to weave the aspect into the core logic, how to intercept the calling method, and perform security checks, logs, and transactions before and after the interception, which is equivalent to completing all business functions.

On the Java platform, there are 3 ways to weave AOP:

  1. Compilation period: When compiling, the compiler compiles aspect calls into bytecode. This method requires defining new keywords and extending the compiler. AspectJ extends the Java compiler and uses the keyword aspect to implement weaving;
  2. Class loader: When the target class is loaded into the JVM, a special class loader is used to "enhance" the bytecode of the target class;
  3. Runtime: The target objects and aspects are all ordinary Java classes, which are dynamically woven during runtime through the dynamic proxy function of the JVM or third-party libraries.

The easiest way is the third, Spring's AOP implementation is based on JVM dynamic proxy. Because the JVM dynamic proxy requires that the interface must be implemented, if a common class does not have a business interface, it needs to be implemented through third-party libraries such as CGLIB or Javassist

The AOP technology looks mysterious, but in fact, it is essentially a dynamic agent. Let us separate some common functions such as permission checking, logs, transactions, etc. from each business method.

It is important to point out that AOP is very useful for solving specific problems, such as transaction management, because the transaction codes scattered everywhere are almost the same, and the parameters (JDBC Connection) they need are also fixed. Some other specific problems, such as logs, are not so easy to implement, because although the log is simple, it is often necessary to capture local variables when printing the log. If the log is implemented using AOP, we can only output the log in a fixed format. Therefore, use AOP It must be suitable for a specific scenario.

3. Grammar

3.1 Basic concepts
  • Aspect : Aspect, that is, a function that spans multiple core logics, or system concerns;
  • Joinpoin t: join point, which defines where to insert the execution of the aspect in the application process;
  • Pointcut : Pointcut, that is, a set of connection points;
  • Advice : enhanced, refers to actions performed on a specific connection point;
  • Introduction : Introduction refers to dynamically adding a new interface to an existing Java object;
  • Weaving : Weaving refers to the integration of aspects into the execution flow of the program;
  • Interceptor : Interceptor is a way to achieve enhancement;
  • Target Object : target object, that is, the core logical object that actually executes the business;
  • AOP Proxy : AOP proxy is an enhanced object reference held by the client. The AOP proxy in Spring can make JDK dynamic proxy or CGLIB proxy. The former is based on interfaces and the latter is based on subclasses.
3.2 Notification method
  • Pre-notification (@Before)

    • Do enhancement processing before the target method is called, @Before only needs to specify the pointcut expression
  • post notification (@After)

    • Enhancement is done after the target method is completed, regardless of when the target method is successfully completed. @After can specify an entry point expression
  • Return notification (@AfterReturning)

    • After the target method is completed normally, it is enhanced. In addition to specifying the pointcut expression, @AfterReturning can also specify a return value parameter name returning, which represents the return value of the target method
  • Exception notification (@AfterThrowing)

    • It is mainly used to handle unhandled exceptions in the program. In addition to specifying the pointcut expression, @AfterThrowing can also specify a throwing return value parameter name, which can be used to access the exception object thrown in the target method.
  • Surround Notification (@Around)

    • Surround notifications, do enhancement processing before and after the target method is completed. Surround notifications are the most important notification types. Things like transactions and logs are all surrounding notifications. Note that the core of programming is a ProceedingJoinPoint
3.3 How to enable
  1. xml configuration method, configure the following sentence in applicationContext.xml:

    <aop:aspectj-autoproxy />
  2. Annotation method, add @EnableAspectJAutoProxy

    @EnableAspectJAutoProxy
    @SpringBootApplication
    public class Application {
        public static void main(String[] args) {
            //do something
        }
    }

4. Examples

4.1 Define the target class
public class MathCalculator {
    public int div(int x, int y) {
        System.out.println(x / y);
        return x / y;
    }
}
4.2 Define the aspect class and specify the notification method
@Aspect
public class LogAspects {
    @Pointcut("execution(int com.test.tornesol.util.spring.spring_aop.MathCalculator.div(int,int))")
    public void pointCut() { }

    @Before("com.test.tornesol.util.spring.spring_aop.LogAspects.pointCut()")
    public void logStart(JoinPoint joinPoint) {
        System.out.println(joinPoint.getSignature().getName() + " 除法运行,参数是:" + Arrays.asList(joinPoint.getArgs()));
    }

    @After("com.test.tornesol.util.spring.spring_aop.LogAspects.pointCut()")
    public void logEnd() {
        System.out.println("除法结束");
    }


    @AfterReturning(value = "com.test.tornesol.util.spring.spring_aop.LogAspects.pointCut())", returning = "result")
    public void logReturn2(JoinPoint joinPoint, Object result) {
        System.out.println(joinPoint.getSignature().getName() + "除法返回" + result);
    }

    @AfterThrowing(value = "com.test.tornesol.util.spring.spring_aop.LogAspects.pointCut()", throwing = "exception")
    public void logException(Exception exception) {
        System.out.println("除法异常");
    }
}
Notes : Note that the @Aspect annotation is added to the aspect class
4.3 Add the Configuration class, inject the target class and aspect class, and turn on the AOP proxy mode
@Configuration
@EnableAspectJAutoProxy//开启基于注解的AOP模式
public class MainConfig {
    @Bean
    public MathCalculator mathCalculator() {
        return new MathCalculator();
    }
    @Bean
    public LogAspects logAspects() {
        return new LogAspects();
    }
}
4.4 Test output
public class AopDemo {
    static public void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
        context.getBean(MathCalculator.class).div(4, 2);
    }
}
div 除法运行,参数是:[4, 2]
2
除法结束
div除法返回2

5. Reference documents

  1. uses AOP-Liao Xuefeng’s official website (liaoxuefeng.com) , Liao Xuefeng’s documentation is pretty good, and can be used to quickly learn about AOP.
  2. Aspect Oriented Programming With Spring , Spring’s official document is the most authoritative and detailed

莫小点还有救
219 声望26 粉丝

优秀是一种习惯!