Jujiu cage, in the river. A fair lady, a gentleman’s bride.

https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2019/2/19/1690484302c4d39c~tplv-t2oaga2asx-image.image

An overview of the

AOP (Aspect Orient Programming), commonly referred to as aspect-oriented Programming, is used as a complement to object orientation to address cross-cutting concerns that are distributed across modules in a system, such as transaction management, logging, caching, and so on. Spring AOP uses dynamic proxies and enhances business methods at run time so that no new classes are generated. Spring AOP provides support for JDK dynamic proxies as well as CGLib support. Instead of focusing on the implementation of aop proxy classes in this chapter, I’ll simply implement a chain call in a specified order.

Implementation of the chain call

MethodInterceptor defines the chain of interceptors, and MethodInvocation recurses into the next chain of interceptors. The class diagram is as follows:

https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2019/2/19/1690484302ab3847~tplv-t2oaga2asx-image.image

MethodInterceptor

public interface MethodInterceptor {

    Object invoke(MethodInvocation invocation) throws Throwable;
}
Copy the code

MethodInvocation

public interface MethodInvocation {

    Object proceed(a) throws Throwable;
}
Copy the code

AbstractAspectJAdvice

Abstract class that implements MethodInterceptor

public abstract class AbstractAspectJAdvice implements MethodInterceptor{

    private Method adviceMethod;

    private Object adviceObject;

    public AbstractAspectJAdvice(Method adviceMethod, Object adviceObject) {
        this.adviceMethod = adviceMethod;
        this.adviceObject = adviceObject;
    }

    public Method getAdviceMethod(a) {
        return this.adviceMethod;
    }

    public void invokeAdviceMethod(a) throws Throwable { adviceMethod.invoke(adviceObject); }}Copy the code

AspectJBeforeAdvice

Pre notice

public class AspectJBeforeAdvice extends AbstractAspectJAdvice {

    public AspectJBeforeAdvice(Method method, Object adviceObject) {
        super(method, adviceObject);
    }

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable{
        this.invokeAdviceMethod();
        Object o = invocation.proceed();
        returno; }}Copy the code

AspectJAfterReturningAdvice

The rear notice

public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice {

    public AspectJAfterReturningAdvice(Method method, Object adviceObject) {
        super(method, adviceObject);
    }

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable{
        Object o = invocation.proceed();
        this.invokeAdviceMethod();
        returno; }}Copy the code

ReflectiveMethodInvocation

MethodInvocation, proceed() recursive chain invocation.

public class ReflectiveMethodInvocation implements MethodInvocation {

    private final Object targetObject;

    private final Method targetMethod;

    private final List<MethodInterceptor> interceptorList;

    private int currentInterceptorIndex = -1;

    public ReflectiveMethodInvocation(Object targetObject, Method targetMethod, List<MethodInterceptor> interceptorList) {
        this.targetObject = targetObject;
        this.targetMethod = targetMethod;
        this.interceptorList = interceptorList;
    }

    @Override
    public Object proceed(a) throws Throwable {

        if (this.currentInterceptorIndex == this.interceptorList.size() - 1) {
            return invokeJoinPoint();
        }

        this.currentInterceptorIndex++;

        MethodInterceptor interceptor =
                this.interceptorList.get(this.currentInterceptorIndex);
        return interceptor.invoke(this);
    }

    private Object invokeJoinPoint(a) throws Throwable {

        return this.targetMethod.invoke(this.targetObject); }}Copy the code

NioCoderService

Mock service class

public class NioCoderService {

    public void testAop(a) {
        System.out.println("http://niocoder.com/"); }}Copy the code

TransactionManager

Mock notification class

public class TransactionManager {
    public void start(a) {
        System.out.println("start tx");
    }

    public void commit(a) {
        System.out.println("commit tx");
    }

    public void rollback(a) {
        System.out.println("rollback tx"); }}Copy the code

ReflectiveMethodInvocationTest

beforeAdvice->afterReturningAdvice

Test classes, test notifications

public class ReflectiveMethodInvocationTest {

    private AspectJBeforeAdvice beforeAdvice = null;

    private AspectJAfterReturningAdvice afterReturningAdvice = null;

    private NioCoderService nioCoderService;

    private TransactionManager tx;

    public void setUp(a) throws Exception {
        nioCoderService = new NioCoderService();
        tx = new TransactionManager();
        beforeAdvice = new AspectJBeforeAdvice(TransactionManager.class.getMethod("start"), tx);
        afterReturningAdvice = new AspectJAfterReturningAdvice(TransactionManager.class.getMethod("commit"), tx);
    }

    public void testMethodInvocation(a) throws Throwable {
        Method method = NioCoderService.class.getMethod("testAop");
        List<MethodInterceptor> interceptorList = new ArrayList<>();
        interceptorList.add(beforeAdvice);
        interceptorList.add(afterReturningAdvice);        

        ReflectiveMethodInvocation mi = new ReflectiveMethodInvocation(nioCoderService, method, interceptorList);

        mi.proceed();
    }


    public static void main(String[] args) throws Throwable {
        ReflectiveMethodInvocationTest reflectiveMethodInvocationTest = newReflectiveMethodInvocationTest(); reflectiveMethodInvocationTest.setUp(); reflectiveMethodInvocationTest.testMethodInvocation(); }}Copy the code

Output:

start tx
http://niocoder.com/
commit tx
Copy the code
Sequence diagram beforeAdvice – > afterReturningAdvice

https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2019/2/19/16904843029513d0~tplv-t2oaga2asx-image.image

https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2019/2/19/1690484302f456e8~tplv-t2oaga2asx-image.image

afterReturningAdvice->beforeAdvice

Change the order of the interceptorList

  public void testMethodInvocation(a) throws Throwable {
        Method method = NioCoderService.class.getMethod("testAop");
        List<MethodInterceptor> interceptorList = new ArrayList<>();
        interceptorList.add(afterReturningAdvice);
		 interceptorList.add(beforeAdvice);

        ReflectiveMethodInvocation mi = new ReflectiveMethodInvocation(nioCoderService, method, interceptorList);

        mi.proceed();
    }
Copy the code

Output:

start tx
http://niocoder.com/
commit tx
Copy the code
Sequence diagram afterReturningAdvice – > beforeAdvice

https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2019/2/19/1690484302fbb1c2~tplv-t2oaga2asx-image.image

https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2019/2/19/169048430309ea9f~tplv-t2oaga2asx-image.image

The code download

  • Github:github.com/longfeizhen…

The code download

  • Github:github.com/longfeizhen…