AOP spring source code analysis

Examples 1 AOP achieved in the case of New

public class TraceTest {

    public static void main(String args[]) {
        TraceTest test = new TraceTest();
        test.rpcCall();
    }

    // 虽然 intellij 没有给出提示,但是这个 Trace 还是成功的
    @Trace
    public void rpcCall() {
        System.out.println("call rpc");
    }

}

@Aspect
public class TraceAspect {
    @Pointcut("@annotation(Trace)")
    public void tracePointcutDefinition() {}

    @Around("@annotation(Trace) && execution(* *(..))")
    public Object aroundTrace(ProceedingJoinPoint pjp) throws Throwable {
        Object returnObj = null;

        try {
            System.out.println("before traced method started...");
            returnObj = pjp.proceed();

        } catch (Throwable throwable) {
            throw throwable;
        } finally {
            System.out.println("after traced method executed...");
        }

        return returnObj;
    }
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Trace {
}

//before traced method started...
//call rpc
//after traced method executed...

Ordinarily used Spring AOP is needed to inject the container, since the container will automatically inject the required code into the generated proxy class, but directly from the above example we New an example, but this example is out of the new has been woven into the code, then it is how to achieve it?

When compiled and run the AOP injection, the above example has been compiled injection finished, resulting .class files already after the modification, and does not require the use of containers, arranged look pom

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <version>1.7</version>
    <configuration>
        <complianceLevel>1.8</complianceLevel>
        <source>1.8</source>
        <target>1.8</target>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>compile</goal>
            </goals>
        </execution>
    </executions>
</plugin>


public void rpcCall();
  Code:
     0: getstatic     #46                 // Field ajc$tjp_0:Lorg/aspectj/lang/JoinPoint$StaticPart;
     3: aload_0
     4: aload_0
     5: invokestatic  #52                 // Method org/aspectj/runtime/reflect/Factory.makeJP:(Lorg/aspectj/lang/JoinPoint$StaticPart;Ljava/lang/Object;Ljava/lang/Object;)Lorg/aspectj/lang/JoinPoint;
     8: astore_1
     9: aload_0
    10: aload_1
    11: invokestatic  #71                 // Method aspectjaop/annotation/TraceAspect.aspectOf:()Laspectjaop/annotation/TraceAspect;
    14: aload_1
    15: checkcast     #59                 // class org/aspectj/lang/ProceedingJoinPoint
    18: invokestatic  #75                 // Method rpcCall_aroundBody1$advice:(Laspectjaop/annotation/TraceTest;Lorg/aspectj/lang/JoinPoint;Laspectjaop/annotation/TraceAspect;Lorg/aspectj/lang/ProceedingJoinPoint;)Ljava/lang/Object;
    21: pop
    22: return

So, maven aspectj plug-in code that will compile time woven into the generated .class file, which is a way of AOP

Examples 2 Spring AOP

We need to study that Spring AOP

public class Logging {
    public void beforeAdvice() {
        System.out.println("Going to setup student profile.");
    }

    public void afterAdvice() {
        System.out.println("Student profile has been setup.");
    }

    public void afterReturningAdvice(Object retVal) {
        System.out.println("Returning returning advice ***** :");
    }

    public void AfterThrowingAdvice(IllegalArgumentException ex) {
        System.out.println("There has been an exception: " + ex.toString());
    }
}

public class Student {
    private int age;
    private String name;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void ExceptionRaised() {
        System.out.println("this is exception message ");
    }
}


public class MainApp {
    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean.xml");

        Student student = (Student) context.getBean("student");

        student.getName();
        student.getAge();

        student.ExceptionRaised();
    }
}
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>4.3.4.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.8.10</version>
</dependency>

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.10</version>
</dependency>

The first example does not require aspectjweaver but the second example was unavoidable. The first example of the need aspectj-maven-plugin but the second example is not needed, because the spring context will be hosting the injection process, the subsequent chapters of Spring is used to analyze an example of how Spring AOP is implemented, help research Example 2 code is the

Let's analyze the application process AOP. Because the case is not woven into the code type of interface, the agent should be dynamic and not JdkDynamicProxy CGLIB

Entry point for the analysis is a function of getProxy, know that cglib of getProxy function, put a breakpoint in the body of the function, according to the return function, it is possible to know the entire call stack, call stack can also be found directly from the thread stack intellij idea of.

AbstractAutowireCapableBeanFactory.doCreateBean()
AbstractAutowireCapableBeanFactory.initializeBean()
AbstractAutowireCapableBeanFactory.postProcessBeforeInitialization()
AbstractAutowireCapableBeanFactory.postProcessAfterInitialization()
    AbstractAdvisorAutoProxyCreator.createProxy
        DefaultAopProxyFactory.createAopProxy // 这里选择 JdkDynamicProxy 或者 CGLibProxy
            createProxy// 根据具体选取的 AOP proxy 构造代理实例

From the above agents, the following can clear a few points:

  1. For each to generate Bean, must be checked if it is injected code when PostProcessor. Check the position of the AbstractAdvisorAutoProxyCreator.findElibleAdvisor for Bean returned List advisor, advisor to achieve many of the subclass PostProcessor
  2. Aspect definition will be converted into AspectJPointcutAdvisor, Advisor divided into two parts, the first part is the second part is Pointcut Advice, Advice note part, noted that in the interface Advisor only advice without pointcut, including subtypes called pointcut AspectJPointcutAdvisor. Each annotation generate a Advisor, Advisor the pointcut is annotated content, its function is to achieve advice portion, to achieve a function of a reference method, such as those in the method is to advice LoggingService
  3. JdkDynamicProxy is a subclass of InvocationHandler and AopProxy, its member variables AdvisedSupport, so each instance of a corresponding one of Bean JdkDynamicProxy
  4. advisor holding advice(action to take at joint point, and a filter to determining the capability of the advice)
  5. pointcut is compose of a class filter and method matcher
  6. ReflectiveInterceptor.proceed. Whether or jdkDynamic cglib are converted into MethodInterceptor

Look at the code when there are still places do not understand

  1. Why should BeanDefinition? Why can not save this one? A BeanDefinition describes a bean instance, which has property values, constructor argument values, and further information supplied by concrete implementations.

In fact Cglib construct dynamic proxy is still pretty simple way, without too much analysis. It is to find a variety of advisor and a variety of set enhancer on the line, but on the other hand, JdkDynamicProxy more complicated, because JdkDynamicProxy construction method is somewhat complex. First, JdkDynamicProxy need to use advisedSupport, fill advisor and targetClass inside then JdkDynamicProxy inherited InvocationHandler

Original: Big Box  AOP spring source code analysis


Guess you like

Origin www.cnblogs.com/chinatrump/p/11612106.html