[Spring aop] Connection point (Jointpoint), entry point (Pointcut), enhancement (Advice), aspect/aspect (Aspect, Advisor)

Preface

The last chapter "Static Proxy Mode and JDK, CGLIB Dynamic Proxy" analyzed static proxy and JDK, CGLIB dynamic proxy. Next, we will review some related knowledge of AOP to facilitate the next analysis of the source code of AOP. ready.

1. Let’s review some terms in AOP first

  • Connection point (Jointpoint): expressed the need to insert cross-section in the program concerns the extension point, the connection point may be the class initialization method of execution, method calls, field calls or handle exceptions and so on , the Spring supports only method execution as the connection point , Expressed in AOP as "where to do it";

    It is a resource that is allowed as an entry point, and all methods of all classes can be used as connection points

  • Pointcut: Select a set of related connection point patterns, which can be considered as a collection of connection points. Spring supports perl5 regular expressions and AspectJ pointcut patterns. Spring uses AspectJ syntax by default, which is expressed in AOP as "Where do you do it?" Collection";

    It is to select some connection points, which can be one or more. For example, there are two methods of request() and request2() in class A. All the places where request() of class A is called can be selected as the cut point.

  • Enhancement (Advice): In many places, it is understood as notification, but it is understood as enhancement to be more accurate. Enhancement means the behavior performed on the connection point. Enhancement provides the need to extend the existing behavior at the connection point selected by the entry point in AOP Means; including pre-enhancement (before advice), post-enhancement (after advice), surround enhancement (around advice) , in Spring through the proxy mode to achieve AOP, and through the interceptor mode to surround the connection point of the interceptor chain weaving Incoming enhancement; expressed as "what to do" in AOP;

    Including two concepts: one is to choose the timing, you can choose front, back, or surround; the other is what to do: take the front as an example, in the before method, user-enhanced logic will be implemented.

  • Aspect/Aspect (also known as Advisor): Modularization of cross-cutting concerns, such as the log component mentioned above. It can be considered as a combination of enhancement, introduction and entry points; in Spring, Schema and @AspectJ can be used for organization and realization; in AOP, it is expressed as "where and what collection";

    It is the combination of the previous concepts that is a complete thing. For example, perform enhancement operations before the request() method of class A is called. One is indispensable, the request() method is missing, and I don’t know where to do it; without the before(), I don’t know when to perform the enhancement operation, and I don’t know what to enhance.


    Advisor=Advice+Pointcut

  • Inter-type declaration: Introduction enhancement is a special enhancement. Instead of weaving enhancements around the target method, it creates new methods or attributes for the target class. Therefore, the connection point of the introduction enhancement is at the class level. , Instead of at the method level , Spring allows the introduction of a new interface (which must correspond to an implementation) to all proxied objects (target objects), which is expressed in AOP as "what to do (what to introduce)";

  • Target Object: The object that needs to be woven into the cross-cutting concerns, that is, the object is the object selected by the entry point, and the object that needs to be enhanced, which can also be called the "enhanced object"; because Spring AOP uses a proxy The pattern is realized, so that this object is always a proxy object, which is expressed as "to whom" in AOP;

  • AOP Proxy (AOP Proxy): The AOP framework uses the objects created by the proxy mode to insert enhancements (ie application aspects) at the connection point, which is to apply aspects to the target object through the proxy. In Spring, AOP proxy can be implemented with JDK dynamic proxy or CGLIB proxy, and the aspect is applied through the interceptor model.

  • Weaving: Weaving is a process of applying aspects to target objects to create AOP proxy objects. Weaving can be done during compilation, class loading, and runtime.

The concepts mentioned above are relatively abstract and boring, and the use of aspect programming in actual development only accounts for a small part, but if you don’t understand the above concepts, then the next source code analysis must be nothing. Mist, let's use a few more examples below to let everyone understand the above concepts and prepare for source code analysis.

2. Introduction to enhancement methods

There are also many people who understand enhancement as notification, but it is more accurate to understand as enhancement because it represents the behavior performed at the connection point. This behavior is not available in the target class. It adds additional methods or other methods to the target class. Some functions, so it is understood that enhancements are more appropriate than notifications. Of course, it does not matter if some people are used to the concept of notifications, as long as you know that the enhancements in this article are notifications.

The types of enhancement include pre-enhancement, post-return enhancement, abnormal enhancement, surround enhancement, introduction enhancement, post-final enhancement and so on. Let’s take a look at the examples below. In order to give you a deeper understanding of SpringAop, we will not explain the way based on @AspectJ or Schema configuration files at the beginning, but start from the very basics. After all, AOP is in In actual development, it does not account for a large proportion. I believe many people do not have a deep understanding.

Next, we first explain the enhancements implemented in coding based on the Advice interface.

2.1 MethodBeforeAdvice pre-enhancement

Target interface and implementation class:

package com.lyc.cn.v2.day04.advisor;

public interface Animal {
    
    
    void sayHello(String name,int age);
    void sayException(String name,int age);
}
package com.lyc.cn.v2.day04.advisor;

public class Dog implements Animal {
    
    

    @Override
    public void sayHello(String name, int age) {
    
    
        System.out.println("==名字:" + name + " 年龄:" + age);
    }

    @Override
    public void sayException(String name, int age) {
    
    
        System.out.println("==名字:" + name + " 年龄:" + age);
        System.out.println("==抛出异常:" + 1 / 0);
    }
}

Pre-enhanced MethodBeforeAdvice:

package com.lyc.cn.v2.day04.advisor;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;

public class MyMethodBeforeAdvice implements MethodBeforeAdvice {
    
    
   
    public void before(Method method, Object[] args, Object target) throws Throwable {
    
    
        System.out.println("==前置增强");
        System.out.println("==方法名:" + method.getName());
        if (null != args && args.length > 0) {
    
    
            for (int i = 0; i < args.length; i++) {
    
    
                System.out.println("==第" + (i + 1) + "参数:" + args[i]);
            }
        }
        System.out.println("==目标类信息:" + target.toString());
    }
}

2.2 AfterReturningAdvice post enhancement

package com.lyc.cn.v2.day04.advisor;
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;

/**
 * 后置增强
 * @author: LiYanChao
 * @create: 2018-11-01 22:09
 */
public class MyAfterReturningAdvice implements AfterReturningAdvice {
    
    
    /**
     * Callback after a given method successfully returned.
     * @param returnValue the value returned by the method, if any
     * @param method      method being invoked
     * @param args        arguments to the method
     * @param target      target of the method invocation. May be {@code null}.
     * @throws Throwable if this object wishes to abort the call.
     *                   Any exception thrown will be returned to the caller if it's
     *                   allowed by the method signature. Otherwise the exception
     *                   will be wrapped as a runtime exception.
     */
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
    
    
        System.out.println("==后置增强");
        System.out.println("==方法名:" + method.getName());
        if (null != args && args.length > 0) {
    
    
            for (int i = 0; i < args.length; i++) {
    
    
                System.out.println("==第" + (i + 1) + "参数:" + args[i]);
            }
        }
        System.out.println("==目标类信息:" + target.toString());
    }
}

2.3 ThrowsAdvice exception enhancement

package com.lyc.cn.v2.day04.advisor;
import org.springframework.aop.ThrowsAdvice;
import java.lang.reflect.Method;

/**
 * @author: LiYanChao
 * @create: 2018-11-01 22:17
 */
public class MyThrowsAdvice implements ThrowsAdvice {
    
    

    /**
     * 异常增强
     */
    public void afterThrowing(Method method, Object[] args, Object target, Exception ex) {
    
    
        System.out.println("==异常增强");
        System.out.println("==方法名:" + method.getName());
        if (null != args && args.length > 0) {
    
    
            for (int i = 0; i < args.length; i++) {
    
    
                System.out.println("==第" + (i + 1) + "参数:" + args[i]);
            }
        }
        System.out.println("==目标类信息:" + target.toString());
        System.out.println("==异常信息:" + ex.toString());
    }
}

2.4 MethodInterceptor surround enhancement

package com.lyc.cn.v2.day04.advisor;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

/**
 * 环绕增强
 * @author: LiYanChao
 * @create: 2018-11-01 22:29
 */
public class MyMethodInterceptor implements MethodInterceptor {
    
    

    /**
     * 环绕增强 这里的方法参数与之前的前置增强、后置增强明显不同,只有一个MethodInvocation类型的参数
     * Implement this method to perform extra treatments before and
     * after the invocation. Polite implementations would certainly
     * like to invoke {@link Joinpoint#proceed()}.
     * @param invocation the method invocation joinpoint
     * @return the result of the call to {@link Joinpoint#proceed()};
     * might be intercepted by the interceptor
     * @throws Throwable if the interceptors or the target object
     *                   throws an exception
     */
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
    
    
        System.out.println("==环绕增强开始");
        System.out.println("==方法名:" + invocation.getMethod().getName());
        Object[] args = invocation.getArguments();
        if (null != args && args.length > 0) {
    
    
            for (int i = 0; i < args.length; i++) {
    
    
                System.out.println("==第" + (i + 1) + "参数:" + args[i]);
            }
        }

        Object proceed = invocation.proceed();

        System.out.println("==环绕增强结束");
        return proceed;
    }
}

2.5 Execution results

@Test
public void test5() {
    
    
    // 前置增强
    // 1、实例化bean和增强
    Animal dog = new Dog();
    MyMethodBeforeAdvice advice = new MyMethodBeforeAdvice();

    // 2、创建ProxyFactory并设置代理目标和增强
    ProxyFactory proxyFactory = new ProxyFactory();
    proxyFactory.setTarget(dog);
    proxyFactory.addAdvice(advice);

    // 3、生成代理实例
    Animal proxyDog = (Animal) proxyFactory.getProxy();
    proxyDog.sayHello("二哈", 3);
}


@Test
public void test6() {
    
    
    // 后置增强
    // 1、实例化bean和增强
    Animal dog = new Dog();
    MyAfterReturningAdvice advice = new MyAfterReturningAdvice();

    // 2、创建ProxyFactory并设置代理目标和增强
    ProxyFactory proxyFactory = new ProxyFactory();
    proxyFactory.setTarget(dog);
    proxyFactory.addAdvice(advice);

    // 3、生成代理实例
    Animal proxyDog = (Animal) proxyFactory.getProxy();
    proxyDog.sayHello("二哈", 3);

}

@Test
public void test7() {
    
    
    // 异常增强
    // 1、实例化bean和增强
    Animal dog = new Dog();
    MyThrowsAdvice advice = new MyThrowsAdvice();

    // 2、创建ProxyFactory并设置代理目标和增强
    ProxyFactory proxyFactory = new ProxyFactory();
    proxyFactory.setTarget(dog);
    proxyFactory.addAdvice(advice);

    // 3、生成代理实例
    Animal proxyDog = (Animal) proxyFactory.getProxy();
    proxyDog.sayException("二哈", 3);

}


@Test
public void test8() {
    
    
    // 环绕增强
    // 1、实例化bean和增强
    Animal dog = new Dog();
    MyMethodInterceptor advice = new MyMethodInterceptor();

    // 2、创建ProxyFactory并设置代理目标和增强
    ProxyFactory proxyFactory = new ProxyFactory();
    proxyFactory.setTarget(dog);
    proxyFactory.addAdvice(advice);

    // 3、生成代理实例
    Animal proxyDog = (Animal) proxyFactory.getProxy();
    proxyDog.sayHello("二哈", 3);

}

3. Summary

The above briefly introduces the encoding implementation of pre-enhancement, post-enhancement, surround enhancement, and abnormal enhancement. Of course, the above implementation can also be implemented through configuration files.

The knowledge points introduced in this article are relatively simple, but understanding the concept of enhancement is the basis of AOP. In fact, the various enhancement methods in this article can be implemented with the dynamic proxy explained in the previous article, because the agent factory used in this article is ProxyFactoryinternal What is used is CglibAopProxyor JdkDynamicAopProxy, in fact, its essence is still JDK or CGLIB dynamic proxy. In the following chapters, the implementation of CglibAopProxy or JdkDynamicAopProxy will be explained in detail. The analysis of this article is here.


reference:

"28-Aop knowledge points review and enhanced implementation based on Advice interface"

Guess you like

Origin blog.csdn.net/m0_45406092/article/details/115243643