在Spring AOP中使用代理

时间:2011-11-22 09:24:05

标签: java spring aop aspectj

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

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

  

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

     

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


我无法得到第二段。 “接口”的含义不可用'。任何人都可以通过一个例子说明这一点吗?

4 个答案:

答案 0 :(得分:27)

Spring AOP使用JDK动态代理或CGLIB为目标对象创建代理。

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

这是强制创建CGLIB代理的方法(设置proxy-target-class =“ true ”):

 <aop:config proxy-target-class="true">
    <!-- other beans defined here... -->
 </aop:config>

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

<aop:aspectj-autoproxy proxy-target-class="true"/>

有关详细信息,请参阅Aspect Oriented Programming with Spring文档的代理机制部分。

答案 1 :(得分:20)

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

比如说我有一个接口MyService

public interface MyService {
    void doSomething();
}

实施MyServiceImpl

@Service
public class MyServiceImpl implements MyService {
    public void doSomething() {
        // does something!
    }
}

如果Spring发现您已经为MyService配置了方面,它将创建一个实现MyService的JDK代理,然后将所有调用代理到您的MyServiceImpl bean,添加方面功能在适当的地方。

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

答案 2 :(得分:6)

我找到了一个博客here,清楚地解释了AOP,Caching&amp;事务使用运行时代理类。

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

  

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

答案 3 :(得分:5)

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

要实现此目的,有两个选项,具体取决于原始对象是否实现了接口。

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

在第二种情况下(原始对象 NOT 实现任何接口),因此必须使用更精细的技巧,这就是CGLIB出现的时候。根据项目页面“CGLIB用于扩展Java类并在运行时实现接口”。因此,在这种情况下,诀窍在于创建一个 EXTENDS 原始对象的代理,因此可以代之以使用。