在Spring AOP中,每次创建目标bean时Spring是否会创建代理对象,或者只是第一次发生?

时间:2017-11-06 09:56:57

标签: java spring proxy spring-aop

每次创建目标bean时spring是否会创建代理对象,或者只是第一次在Spring AOP中发生?

1 个答案:

答案 0 :(得分:4)

编织是一种将目标类方面交织在一起的技术,以便在出现合适的条件时执行建议。

AspectJ 提供三种类型的编织机制,即:源代码编织二元编织加载编织

虽然 Spring AOP 仅提供运行时编织

编织类型

1。源编织

源代码编译是编译过程的一部分,其中Java源代码(*.java)使用AspectJ编译器(ajc)编译为编织字节码(*.class)。这里,ajc替换javac(Java编译器)。

Target.java + MyAspect.java -- (compiled with ajc) --> Target.class

2。二元编织

在二进制编织中,目标和方面源代码(*.java)分别编译为二进制类(.class)。然后将二进制类与AspectJ编译器(ajc)编织在一起。

第1步:编译目标类

Target.java -- (compiled with javac) --> Target.class

第2步:编译Aspect类

MyAspect.java -- (compiled with javac or ajc) --> MyAspect.class

第3步。方面编织

Target.class + MyAspect.class -- (woven with ajc) --> Target.class

3。装载编织

在加载编织中,二进制目标和方面类(*.class)在JVM加载类时使用instrumented等技术进行修改(javaagent)。

4。运行时编织

由于Spring框架固有的基于代理的特性,Spring AOP仅提供运行时编织。这意味着在应用程序启动期间(或在运行时使用之前的任何其他时间),目标类实例将更改为代理。目标代理类相应地拦截对目标方法的任何调用,以执行任何合适的建议。

问题

  

每次创建目标bean时Spring是否会创建代理对象,或者只是第一次在Spring AOP中发生?

假设您已经在名为create的控制器名为BookController的方法上创建了一个方面。

  • 在应用程序启动期间,Spring框架实例化目标bean BookController,并创建目标类的代理。 目标类的代理只创建一次
  • 如果目标类没有实现任何接口,则代理的类型为CglibAopProxy。否则,代理的类型为JdkDynamicAopProxy
  • 每次调用目标类的create方法BookController时,Spring框架会在传递它之前将原始代理包装在连接点(本例中为MethodInvocationProceedingJoinPoint)中在你的方面。
  

Spring AOP仅支持运行时编织,这是否意味着只有在第一次调用目标方法时才会创建目标代理?

当Spring AOP声明运行时,它试图区分AspectJ中其他类型的编织。 Spring运行时可以表示Spring应用程序运行时的任何时间。

关于何时创建代理的问题,可以懒惰或主动创建。在大多数情况下,目标类在Spring应用程序启动期间被代理。

在上面的示例中,即使在调用控制器上的任何方法之前,即在控制台中记录底线之前,控制器实例也会变为代理。

2017-11-07 20:12:27.541 INFO 31394 --- [ main] com.basaki.Application : Started Application in 147.808 seconds (JVM running for 149.184)