【问题标题】:In Spring AOP, does spring creates proxy object every time a target bean is created or it happens only first time?在 Spring AOP 中,spring 是在每次创建目标 bean 时创建代理对象还是仅第一次发生?
【发布时间】:2017-11-06 09:56:56
【问题描述】:

spring 是在每次创建目标 bean 时创建代理对象还是仅在 Spring AOP 中第一次发生?

【问题讨论】:

    标签: java spring proxy spring-aop


    【解决方案1】:

    编织

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

    AspectJ提供三种编织机制,分别是:source weavingbinary weavingload weaving .

    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 使用 javaagent 等技术加载类期间被修改 (instrumented)。

    4。运行时编织

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

    问题

    Spring 是在每次创建目标 bean 时创建代理对象还是仅在 Spring AOP 中第一次发生?

    假设您在名为 create 的控制器的名为 create 的方法上创建了一个切面,该控制器名为 BookController

    • 在应用程序启动期间,Spring 框架实例化目标 bean,BookController,并创建目标类的代理。 目标类的代理只创建一次
    • 如果目标类没有实现任何接口,则代理的类型为CglibAopProxy。否则,代理的类型为 JdkDynamicAopProxy
    • 每次调用目标类BookControllercreate 方法时,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)

    【讨论】:

    • 有一个疑问,你提到了在应用启动时会创建代理,但是Spring AOP只支持运行时编织,所以第一次调用目标方法时不应该创建代理吗?
    • 更新了我的帖子。希望它能回答您的问题。
    猜你喜欢
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 2017-05-16
    • 1970-01-01
    • 1970-01-01
    • 2015-03-01
    • 2014-03-09
    相关资源
    最近更新 更多