我正在读一本关于在Spring AOP中启用AspectJ支持的书 .
以下是从该书中摘录的一段:
要在Spring IoC容器中启用AspectJ注释支持,您只需在bean配置文件中定义一个空的XML元素aop:aspectj-autoproxy . 然后,Spring将自动为您的AspectJ方面匹配的任何bean创建代理 . 对于接口不可用或未在应用程序设计中使用的情况,可以依靠CGLIB创建代理 . 要启用CGLIB,您需要在<aop:aspectj-autoproxy />中设置属性proxy-target-class = true .
我无法得到第二段 . '接口不可用'是什么意思 . 任何人都可以用一个例子说明这一点
4 回答
我发现了一个博客here,它清楚地解释了AOP,Caching和Transaction如何使用运行时代理类 .
什么时候不编码接口(引自博客's section ' What if the bean class does not implement any interface? '): -
Spring AOP使用JDK动态代理或CGLIB来创建目标对象的代理 .
根据Spring文档,如果您的目标实现至少一个接口,将使用JDK动态代理 . 但是,如果目标对象未实现任何接口,则将创建CGLIB代理 .
这是您可以强制创建CGLIB代理的方法(set proxy-target-class =“ true ”):
使用AspectJ及其autopoxy支持时,您也可以强制使用CGLIB代理 . 这是
<aop:aspectj-autoproxy>
的使用位置,此处"proxy-target-class"必须设置为 true :有关更多详细信息,请参阅Aspect Oriented Programming with Spring文档的代理机制部分 .
Spring更喜欢使用AOP接口,因为它可以使用JDK proxies .
比方说我有一个接口
MyService
并实施
MyServiceImpl
如果Spring发现您已为
MyService
配置了方面,它将创建一个实现MyService
的JDK代理,然后将所有调用代理到您的MyServiceImpl
bean,并在适当的位置添加方面功能 .JDK代理通过实现与目标对象相同的接口并委托对它的调用来工作;如果没有可实现的接口,它们将无法工作 . 如果您没有上面的接口,Spring需要使用像CGLIB这样的字节代码库来在运行时动态创建包含方面功能的类 .
Spring AOP广泛使用代理作为以非侵入方式实现跨领域关注(a.k.a方面)的机制,该思想基本上是使用代理作为包装器来丰富原始行为,即添加事务功能 .
为实现此目的,有两个选项,取决于原始对象是否实现接口 .
在第一种情况下(原始对象实现至少一个接口),反射API的动态代理功能用于创建一个代理对象,该代理对象可以代替原始对象和代理的相同接口 .
在第二种情况下(原始对象实现 NOT 实现任何接口),因此必须使用更精细的技巧,这就是CGLIB出现的时候 . 根据项目页面"CGLIB is used to extend Java classes and implements interfaces at runtime" . 因此,在这种情况下,技巧包括创建一个代理 EXTENDS 原始对象,因此可以使用它 .