Spring AOP中代理的使用
我正在读一本书,其中讨论了在 Spring AOP 中启用 AspectJ 支持。
下面是书中的一段话:
要在 Spring IoC 容器中启用 AspectJ 注解支持,您只需定义一个空的 bean 配置文件中的 XML 元素 aop:aspectj-autoproxy。然后Spring会自动 为与 AspectJ 方面匹配的任何 bean 创建代理。
对于接口不可用或未在应用程序设计中使用的情况,可以 依赖CGLIB创建代理。要启用CGLIB,您需要在
中设置属性
proxy-target-class=true
。
我无法理解第二段。 “接口不可用”是什么意思。谁能用一个例子来说明这一点?
I am reading a book, which talks about enabling AspectJ support in Spring AOP.
Given below is a paragraph taken from the book:
To enable AspectJ annotation support in the Spring IoC container, you only have to define an empty
XML element aop:aspectj-autoproxy in your bean configuration file. Then, Spring will automatically
create proxies for any of your beans that are matched by your AspectJ aspects.For cases in which interfaces are not available or not used in an application’s design, it’s possible to
create proxies by relying on CGLIB. To enable CGLIB, you need to set the attributeproxy-target-class=true
in<aop:aspectj-autoproxy />
.
I am not able to get the second paragraph. What is meant by 'interfaces are not available'. Can anyone illustrate this with an example ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Spring AOP 使用 JDK 动态代理或 CGLIB 来为目标对象创建代理。
根据 Spring 文档,如果您的目标至少实现一个接口,则将使用 JDK 动态代理。但是,如果您的目标对象未实现任何接口,则会创建 CGLIB 代理。
这是强制创建 CGLIB 代理的方法(设置 proxy-target-class="true"):
使用 AspectJ 及其 autopoxy 支持时,您还可以强制创建 CGLIB 代理。这是使用
的地方,并且这里的“proxy-target-class”必须设置为true:请参阅代理机制使用 Spring 进行面向方面编程文档部分了解更多详细信息。
Spring AOP uses either JDK dynamic proxies or CGLIB to create the proxies for your target objects.
According to Spring documentation, in case your target implements at least one interface, a JDK dynamic proxy will be used. However if your target object does not implement any interfaces then a CGLIB proxy will be created.
This is how you can force creation of the CGLIB proxies (set proxy-target-class="true"):
When using AspectJ and its autopoxy support you can also force CGLIB proxies. This is where the
<aop:aspectj-autoproxy>
is used and also here the "proxy-target-class" must be set to true:Please refer to Proxying mechanisms section of Aspect Oriented Programming with Spring documentation for more details.
Spring更喜欢使用AOP的接口,因为它可以使用JDK 代理< /a>.
举例来说,我有一个接口
MyService
和一个实现
MyServiceImpl
如果 Spring 发现您已经为
MyService
配置了方面,它将创建一个 JDK实现MyService
的代理,然后将所有调用代理到您的MyServiceImpl
bean,并在适当的情况下添加方面功能。JDK 代理的工作方式是实现与目标对象相同的接口并将调用委托给它;如果没有要实现的接口,它们就不起作用。如果您没有像上面这样的接口,Spring 需要使用像 CGLIB 这样的字节代码库在运行时动态创建包含切面功能的类。
Spring prefers to use interfaces for AOP because it can use JDK proxies.
Say for example I have an interface
MyService
And an implementation
MyServiceImpl
If Spring discovers that you've configured aspects for
MyService
, it will create a JDK Proxy that implementsMyService
and then proxy all calls through to yourMyServiceImpl
bean, adding aspect functionality where appropriate.JDK proxies work by implementing the same interface as your target object and delegating calls to it; they do not work if there is no interface to implement. In case you don't have an interface like above, Spring needs to use a byte code library like CGLIB to dynamically create classes at runtime that incorporate the aspect functionality.
我找到了一个博客 这里清楚地解释了AOP、Caching & 是如何实现的。事务使用运行时代理类进行工作。
当不编码到接口时(引用博客的部分“如果 bean 类没有实现任何接口怎么办?”):-
I found a blog here that clearly explains how AOP,Caching & Transaction works using runtime proxy classes.
When not coding to interface (quoting from the blog's section 'What if the bean class does not implement any interface?'):-
Spring AOP 广泛使用代理作为一种机制,以非侵入式方式实现横切关注点(也称为方面),其思想基本上是使用代理作为丰富原始行为的包装器,即添加事务功能。
要实现此目的,有两种选择,具体取决于原始对象是否实现接口。
在第一种情况下(原始对象实现至少一个接口),反射 API 的动态代理功能用于创建一个代理对象,该对象实现与原始对象相同的接口,因此代理可以来代替使用。
在第二种情况下(原始对象不实现任何接口),因此必须使用更复杂的技巧,这就是 CGLIB 出现的时候。根据项目页面“CGLIB 用于扩展 Java 类并在运行时实现接口”。因此,在这种情况下,技巧在于创建一个代理来扩展原始对象,因此可以替代使用。
Spring AOP makes extensive use of proxies as a mechanism to implement cross-cutting concerns (a.k.a aspects) in a non-intrusive way, the idea basically is use the proxies as wrappers that enrich the original behaviour, i.e. add transactional capabilities.
To achieve this there are two options, depending of whether the original object implements an interface or not.
In the first case (the original object implements at least one interface) the dynamic proxy capabilities of the reflection API are used to create a proxy object that IMPLEMENTS the same interfaces that the original object and therefore the proxy can be used instead.
In the second case (the original object does NOT implement any interface), so a more elaborated trick must be used, and this is when CGLIB appears. According to the project page "CGLIB is used to extend Java classes and implements interfaces at runtime". So in this case the trick consists on create a proxy that EXTENDS the original object and therefore can be used instead.