On spring AOP

Time:2022-5-16

AOP of spring core

What is AOP?

AOP (aspect oriented programming) is a design idea. It is aspect oriented programming in the field of software design. It is a supplement and perfection of object-oriented programming (OOP). It is a technology that adds additional functions to the program dynamically and uniformly without modifying the source code through precompiling and runtime dynamic agent.
As shown in the figure:
On spring AOP

AOP and OOP literally mean very similar, but in fact, they are completely design ideas oriented to different fields. In actual projects, we usually understand object-oriented as a static process (for example, how many modules a system has, what objects a module has, and what properties an object has). The aspect oriented runtime agent mode is understood as a dynamic process, which can dynamically weave some extended functions or control the execution of objects when the objects are running.

Application principle of spring AOP

The bottom layer of spring AOP implements function expansion based on proxy mechanism (dynamic proxy)
Dynamic agent: enhance the existing methods without changing the source code.
1)JDK dynamic agent:If the target object (proxy object) implements the interface, the underlying layer of AOP can use JDK dynamic proxy mechanism to create proxy objects for the target object (the target object and proxy object will implement a common interface).
2)Cglib dynamic proxy:If the target object (proxied object) does not implement the interface, the underlying AOP will use the cglib proxy mechanism to create a proxy object for the target object (the proxy class created by default will inherit the target object type). Note: the target class to be inherited cannot be final modified.

JDK dynamic agent:

The target object is required to implement at least one interface
The class involved is proxy
The method of creating dynamic proxy is: newproxyinstance (classloader, class [], invocationhandler)
User user=new UserImpl();
        /**
         *Parameter meaning:
         *Classloader: class loader, which uses the same class loader as the proxy object;
         *Class []: bytecode array, the interface implemented by the proxy class (the proxy object and the proxy object are required to have the same behavior);
         *Invocationhandler: it is an interface used to provide enhanced code. Generally, it is used to write an implementation class of the interface, which can be an anonymous internal class; Its meaning is how to act as an agent;
         */
        The proxy object interface jdkproxy = (forced conversion required) proxy newProxyInstance(user.getClass(). getClassLoader(),
            user.getClass().getInterfaces(),
            new InvocationHandler() {
                Object result=null
            /**
             *Any method that executes the proxy object must pass through this method, which has the function of interception;
             *Parameters of the method:
             *Object proxy: the reference of proxy object. It may not be used every time
             *Method: the currently executed method
             *Object [] args: parameters required for current method execution
             *Return value: the return value of the currently executed method
             */
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    //Enhance business
                    result=method. Invoke (proxy object, parameters used)// Method of executing the proxied object
                    //Enhance business
                    return result;
                }
            });
            jdkProxy. test();// Business enhancement is realized by calling the method of the proxy object through the proxy object

Cglib dynamic proxy:

Requirement: the proxy class cannot be the final class; Cannot be modified by final;
Class involved: enhancer
Method of creating object: create (class, callback);
UserImpl user=new UserImpl();
        /**
         *Parameter meaning:
         *Class: bytecode of the proxy object
         *Callback: how to proxy is the same as invocationhandler. It is also an interface,
         *Generally, the subclass methodinterceptor of this interface is used; It is also used to create anonymous inner classes of interfaces;
         */
        
        Proxy object cglibproxy = (forced conversion required) enhancer create(user.getClass(),new MethodInterceptor() {
            Object result=null;
            /**
             *Execute any method of the proxied object, which has the same function as the invoke method of JDK dynamic proxy
             *Method parameters:
             *The method parameters of object proxy, method, object [] args and invoke are the same;
             *Methodproxy: the proxy object of the current method, that is, the proxy object of method in the parameter; Generally not
             */
            @Override
            public Object intercept(Object proxy, Method method, Object[] args,MethodProxy methoddProxy) throws Throwable {
                    //Business enhancement
                    result=method. invoke(user, args);// Method of executing the proxied object
                    //Business enhancement
                    return result;
                }
            });
        cglibProxy. test();// Business enhancement is realized by calling the method of the proxy object through the proxy object

As shown in the figure:
On spring AOP

Spring AOP related terms:

  • Aspect:Cross section object, generally a concrete class object (can be declared with the help of @ aspect), is a combination of pointcut and notification.
  • Advice:The action (extended function) executed at a specific connection point of the section is actually enhanced code. For example: around, before, after, etc.
  • Join point:A specific point in the process of program execution generally points to the intercepted target method, which is actually all the methods in the business class interface.
  • Pointcut:A definition of multiple join points can generally be understood as a collection of multiple join points, which is actually an enhanced method.
  • Introduction:Add a method or field to the notified class. Spring allows the introduction of new interfaces to any notified object. For example, you can use an introduction to make any object implement the ismodified interface to simplify caching. To use introduction in spring, you can use delegatingintroductioninterceptor to realize notification, and defaultintroductionadvisor to configure the interface between advice and proxy class. Generally not.
  • Target object:The object that contains the connection point. Also known as the notified or represented object.
  • Weaving:Assemble aspects to create a notified object. This can also be done at runtime using the AspectJ compiler, for example. Spring, like other pure Java AOP frameworks, completes weaving at run time.
  • Proxy:After a class is woven and enhanced by AOP, a result proxy class is generated;

Common notification types in spring:

Before:Always execute before the pointcut method is executed;
After returning:The pointcut method is executed after normal execution;
After throwing:Execute the pointcut method after an exception occurs; He and post notification can only execute one;
After:Whether or not the pointcut method is executed normally, it will be executed after it.
Around:Spring framework provides a way to manually control when the notification method is executed in the code;

Spring provides us with an interface: proceeding joinpoint;
This interface can be used as a parameter around the notification.
There is a method in this interface: proceed (), which is equivalent to method Invoke method,
                    Is to explicitly call the core method of the business layer (entry point method);
For example (XML configuration method):
    public Object aroundTest(ProcesdingJoinPoint pjp) {
        Object result=null;
        try {
            System. out. Println ("advance notice");
            result=pjp. proceed();// Call business layer core methods
            System. out. Println ("post notification");
        
        } catch (Exception e) {
            System. out. Println ("exception notification");
        }finally{
            System. out. Println ("final notice");
        }
        return result;
    }

Pointcut expression in AOP:

Pointcut expression:
            Keyword: execution (expression)
            Expression writing: access modifier return value package name Package name Class name Method name (parameter list)
            Full matching method: execution (public void com. Service. Impl. Xxserviceimpl. Save())
            Full universal configuration mode: execution (* *. *. * (..);
                       ".."  The position written in the package indicates the current package and sub package
                       ".."  It can be written in the parameter to indicate whether there are parameters or not. If there are parameters, it can be any type
            In actual development, the business layer method is generally enhanced, so the general writing method is:
                       * com.service.impl.*.*(..)

General pointcut expression:

<!--  Define a common pointcut expression:
            If it is written inside the AOP: aspect tag, it means that only the current aspect is available
            If it is written outside the AOP: aspect tag, it means that all sections are available; Note: if it is written outside the AOP: aspect tag, it must be written above the AOP: aspect tag
 -->
    <aop:pointcut expression="execution(* com.service.impl.*.*(..))" id="pt"/>
    <!--  Use a generic pointcut expression -- >
    < AOP: before method = "enhanced method name" pointcut ref = "ID value of common pointcut expression (PT)" / >

AOP configuration based on XML:

<?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:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
    <!--  Configure service -- >
    < bean id = "xxxservice" class = "fully qualified class name" > < / bean >
    <!--  Steps of AOP configuration based on XML: note that if you want to use spring AOP, you must import AOP jar package -- >
    <!--  Step 1: give the notification class to spring management. Take the log class as an example -- >
    < bean id = "logger" class = "fully qualified class name" > < / bean >
    <!--  Step 2: import AOP namespace and start AOP configuration with AOP: config -- >
        <aop:config>
            <!--  Step 3: configure the aspect using AOP: aspect.
                        ID attribute: used to provide a unique identification for the section
                        Ref attribute: ID of the application notification bean 
            -->
            <aop:aspect id="logAdvice" ref="logger">
                <!--  Step 4: configure the type of notification and specify when the enhanced method will be executed
                        Method attribute: used to specify the enhanced method name;
                        Pointcut attribute: used to specify the pointcut expression
                 -->
                < AOP: before method = "enhanced method name" pointcut = "execution (public void com. Service. Impl. Xxxserviceimpl. Save())"
            </aop:aspect>
        </aop:config>
</beans>

AOP configuration based on annotation:

Introducing context namespace:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

Packages to scan when configuring the spring registration container:

<!--  Configure packages to be scanned when spring creates containers -- >
< context: component scan base package = "package path" > < / context: component scan >

Enable spring’s support for annotation AOP:

<aop:aspect-autoproxy/>

Implementation of AOP service enhancement:

  1. Add @ service annotation to the business layer (target object) and submit it to spring management;
  2. The notification class needs to be identified with @ Component annotation;
  3. Use the @ aspect annotation to indicate that the notification class is configured with aspect
  4. Notification type configured on notification class method: @ before (“pointcut expression”)
  5. Define a pointcut expression in this class:
@Pointcut("execution(* com.service.impl.*.*(..))")
private void pt(){}
//Reference expression pointcut
@Before("pt()")
public void beforeTest(){
    System. out. Println ("pre notification service enhancement");
}