在Spring AOP中使用代理

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

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

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

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

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

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

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

这是你可以强制创建CGLIB代理的方法(set proxy-target-class =“ true ”):

     

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

  

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

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

比方说,我有一个接口MyService

 public interface MyService { void doSomething(); } 

并实现MyServiceImpl

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

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

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

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

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

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

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

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

在第一种情况下(原始对象实现至少一个接口),reflectionAPI的动态代理function用于创建代理对象,该代理对象实现与原始对象相同的接口,因此可以使用代理。

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