我正在读一本关于在Spring AOP中启用 AspectJ 支持的书。
以下是从该书中摘录的一段:
要在Spring IoC容器中启用AspectJ注释支持,您只需要定义一个空 XML元素aop:bean配置文件中的aspectj-autoproxy。然后,Spring将自动执行 为您的AspectJ方面匹配的任何bean创建代理。
对于接口不可用或未在应用程序设计中使用的情况,可以使用 依靠CGLIB创建代理。要启用CGLIB,您需要在
proxy-target-class=true
中设置属性<aop:aspectj-autoproxy />
。
我无法得到第二段。 “接口”的含义不可用'。任何人都可以通过一个例子说明这一点吗?
答案 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 原始对象的代理,因此可以代之以使用。