【问题标题】:How Spring aspects work internally?Spring方面如何在内部工作?
【发布时间】:2014-12-20 14:05:01
【问题描述】:

Say Service 调用需要应用日志方面(注释)的 Dao 类。我想知道如何 方面实际上得到应用。

根据我在Service对象下注入DAO时的理解,spring发现有一些 方面(在本例中为日志记录)是为 DAO 配置的,因此它注入代理对象而不是实际的目标对象。 现在,当对 DAO 中的任何方法进行实际调用时,代理会应用方面,然后调用实际目标 目的。那是对的吗 ?我也相信这被称为运行时编织。

另一方面,加载时间编织(使用 javaagent 配置)也可以进行字节码操作 是针对需要应用方面的类完成的。所以代理在这里没有出现。

如果我错了,请纠正我,因为这是所有 spring 模块的基础?

【问题讨论】:

    标签: java spring aspectj spring-aop


    【解决方案1】:

    你的理解是对的。 Spring AOP 是基于代理的。 Spring 使用 JDK 代理(即使被代理的目标实现了至少一个接口)或 CGLIB 代理(如果目标对象没有实现任何接口)来为给定的目标 bean 创建代理。

    除非配置为其他方式,否则 Spring AOP 执行运行时编织。但是,您可以设置 Spring 以通过 AspectJ 进行加载时编织。查看documentation link了解更多详情。

    Spring AOP proxying internals的参考

    【讨论】:

    • 我相信加载时间编织在性能方面更好,因为在决定是否需要根据方面配置注入代理时不会产生性能开销,运行时间编织就是这种情况。是的,在加载时间编织服务器启动将需要更长的时间,但作为它的一次性活动没关系
    • 只是一个有用的引用 - “计算机科学中的所有问题都可以通过另一个级别的间接来解决,当然除了太多间接的问题。” - David Wheeler
    • 很好的解释。两个问题 -> 首先:我们可以说 Spring-AOP 使用反射但 aspectJ 没有吗?第二:从效率的角度来看,使用反射不是很昂贵吗?
    • @AmirZiarati 我将尝试回应:1.两者都在使用反射,但 AspectJ“至少使用它”(请参阅​​eclipse.org/aspectj/doc/released/faq.php#q:reflection)2.是的,反射很昂贵,应该小心使用.
    • @AndyDufresne 您指向 Spring AOP 内部的链接不起作用。
    【解决方案2】:

    这里还有两点需要澄清

    我帖子中的第一个实际上是加载时编织而不是运行时编织

    来自link

    加载时编织 (LTW) 只是延迟到类加载器加载类文件并将类定义到 JVM 的点的二进制编织。为了支持这一点,需要一个或多个“编织类加载器”,由运行时环境显式提供或通过“编织代理”启用。

    第二个是编译时编织

    编译时编织是最简单的方法。当您拥有应用程序的源代码时,ajc 将从源代码编译并生成编织类文件作为输出。 weaver 的调用对于 ajc 编译过程是不可或缺的。方面本身可以是源代码或二进制形式。如果受影响的类需要这些方面来编译,那么您必须在编译时进行编织。方面是必需的,例如,当它们向类添加成员并且正在编译的其他类引用添加的成员时。

    【讨论】:

      猜你喜欢
      • 2015-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-12
      • 1970-01-01
      • 2023-03-25
      • 2020-09-10
      相关资源
      最近更新 更多