在Spring AOP中使用代理

use*_*434 22 java aop spring aspectj

我正在读一本关于在Spring AOP中启用AspectJ支持的书.

以下是从该书中摘录的一段:

要在Spring IoC容器中启用AspectJ注释支持,您只需在bean配置文件中定义一个空的XML元素aop:aspectj-autoproxy.然后,Spring将自动为您的AspectJ方面匹配的任何bean创建代理.

对于接口不可用或未在应用程序设计中使用的情况,可以依靠CGLIB创建代理.为了使CGLIB,你需要设置该属性proxy-target-class=true<aop:aspectj-autoproxy />.


我无法得到第二段.' 接口不可用 ' 什么意思.任何人都可以用一个例子说明这一点

now*_*waq 27

Spring AOP使用JDK动态代理或CGLIB来创建目标对象的代理.

根据Spring文档,如果您的目标实现至少一个接口,将使用JDK动态代理.但是,如果目标对象未实现任何接口,则将创建CGLIB代理.

这是强制创建CGLIB代理的方法(set proxy-target-class =" true "):

 <aop:config proxy-target-class="true">
    <!-- other beans defined here... -->
 </aop:config>
Run Code Online (Sandbox Code Playgroud)

使用AspectJ及其autopoxy支持时,您也可以强制使用CGLIB代理.这是使用的地方,<aop:aspectj-autoproxy>此处"proxy-target-class"必须设置为true:

<aop:aspectj-autoproxy proxy-target-class="true"/>
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅面向方面编程与Spring文档的代理机制部分.


ste*_*vls 22

Spring更喜欢使用AOP接口,因为它可以使用JDK 代理.

比方说,我有一个界面 MyService

public interface MyService {
    void doSomething();
}
Run Code Online (Sandbox Code Playgroud)

并实施 MyServiceImpl

@Service
public class MyServiceImpl implements MyService {
    public void doSomething() {
        // does something!
    }
}
Run Code Online (Sandbox Code Playgroud)

如果Spring发现您已为其配置了方面MyService,它将创建一个JDK代理,该代理实现MyService并代理对您的MyServiceImplbean的所有调用,并在适当的位置添加方面功能.

JDK代理通过实现与目标对象相同的接口并委托对它的调用来工作; 如果没有可实现的接口,它们将无法工作.如果您没有上面的接口,Spring需要使用像CGLIB这样的字节代码库来在运行时动态创建包含方面功能的类.


Kum*_*hav 7

我在这里找到了一个博客,清楚地解释了AOP,Caching和Transaction如何使用运行时代理类工作.

当不编码接口时(引用博客的部分' 如果bean类没有实现任何接口怎么办? '): -

默认情况下,如果您的bean没有实现接口,Spring会使用技术继承:在启动时,会创建一个新类.它继承自bean类并在子方法中添加行为.为了生成这样的代理,Spring使用了一个名为cglib的第三方库.


Ale*_*dro 5

Spring AOP广泛使用代理作为以非侵入方式实现跨领域关注(又称方面)的机制,该思想基本上是使用代理作为包装来丰富原始行为,即添加事务功能.

为实现此目的,有两个选项,取决于原始对象是否实现接口.

在第一种情况下(原来的对象实现的至少一个接口)反射API的动态代理功能用于创建一个代理对象IMPLEMENTS原始对象,因此,代理可以用来代替相同的接口.

在第二种情况下(原来的对象不NOT实现任何接口),因此必须使用更精细的特技,这是CGLIB出现时.根据项目页面"CGLIB用于扩展Java类并在运行时实现接口".因此,在这种情况下,技巧包括创建一个扩展原始对象的代理,因此可以使用它.