简体   繁体   English

在Spring AOP中使用代理

[英]Use of proxies in Spring AOP

I am reading a book, which talks about enabling AspectJ support in Spring AOP. 我正在读一本关于在Spring AOP中启用AspectJ支持的书。

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. 要在Spring IoC容器中启用AspectJ注释支持,您只需在bean配置文件中定义一个空的XML元素aop:aspectj-autoproxy。 Then, Spring will automatically create proxies for any of your beans that are matched by your AspectJ aspects. 然后,Spring将自动为您的AspectJ方面匹配的任何bean创建代理。

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. 对于接口不可用或未在应用程序设计中使用的情况,可以依靠CGLIB创建代理。 To enable CGLIB, you need to set the attribute proxy-target-class=true in <aop:aspectj-autoproxy /> . 要启用CGLIB,您需要在<aop:aspectj-autoproxy />设置属性proxy-target-class=true


I am not able to get the second paragraph. 我无法得到第二段。 What is meant by ' interfaces are not available '. ' 接口不可用 ' 什么意思。 Can anyone illustrate this with an example ? 任何人都可以用一个例子说明这一点

Spring AOP uses either JDK dynamic proxies or CGLIB to create the proxies for your target objects. Spring AOP使用JDK动态代理或CGLIB来创建目标对象的代理。

According to Spring documentation, in case your target implements at least one interface, a JDK dynamic proxy will be used. 根据Spring文档,如果您的目标实现至少一个接口,将使用JDK动态代理。 However if your target object does not implement any interfaces then a CGLIB proxy will be created. 但是,如果目标对象未实现任何接口,则将创建CGLIB代理。

This is how you can force creation of the CGLIB proxies (set proxy-target-class=" true "): 这是强制创建CGLIB代理的方法(set proxy-target-class =“ true ”):

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

When using AspectJ and its autopoxy support you can also force CGLIB proxies. 使用AspectJ及其autopoxy支持时,您也可以强制使用CGLIB代理。 This is where the <aop:aspectj-autoproxy> is used and also here the "proxy-target-class" must be set to true : 这是使用<aop:aspectj-autoproxy>的地方,此处“proxy-target-class”必须设置为true

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

Please refer to Proxying mechanisms section of Aspect Oriented Programming with Spring documentation for more details. 有关更多详细信息,请参阅面向方面编程与Spring文档的代理机制部分。

Spring prefers to use interfaces for AOP because it can use JDK proxies . Spring更喜欢使用AOP接口,因为它可以使用JDK 代理

Say for example I have an interface MyService 比方说,我有一个接口MyService

public interface MyService {
    void doSomething();
}

And an implementation MyServiceImpl 并实现MyServiceImpl

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

If Spring discovers that you've configured aspects for MyService , it will create a JDK Proxy that implements MyService and then proxy all calls through to your MyServiceImpl bean, adding aspect functionality where appropriate. 如果Spring发现您已为MyService配置了方面,它将创建一个实现MyService的JDK代理,然后将所有调用代理到MyServiceImpl bean,并在适当的位置添加方面功能。

JDK proxies work by implementing the same interface as your target object and delegating calls to it; JDK代理通过实现与目标对象相同的接口并委托对它的调用来工作; 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. 如果您没有上面的接口,Spring需要使用像CGLIB这样的字节代码库来在运行时动态创建包含方面功能的类。

I found a blog here that clearly explains how AOP,Caching & Transaction works using runtime proxy classes. 我在这里找到了一个博客,清楚地解释了AOP,Caching和Transaction如何使用运行时代理类工作。

When not coding to interface (quoting from the blog's section ' What if the bean class does not implement any interface? '):- 当不编码接口时(引用博客的部分' 如果bean类没有实现任何接口怎么办? '): -

By default, if your bean does not implement an interface, Spring uses technical inheritance: at startup time, a new class is created. 默认情况下,如果您的bean没有实现接口,Spring会使用技术继承:在启动时,会创建一个新类。 It inherits from your bean class and adds behavior in the child methods. 它继承自bean类并在子方法中添加行为。 In order to generate such proxies, Spring uses a third party library called cglib. 为了生成这样的代理,Spring使用了一个名为cglib的第三方库。

Spring AOP makes extensive use of proxies as a mechanism to implement cross-cutting concerns (aka aspects) in a non-intrusive way, the idea basically is use the proxies as wrappers that enrich the original behaviour, ie add transactional capabilities. Spring AOP广泛使用代理作为以非侵入方式实现跨领域关注(又称方面)的机制,该思想基本上是使用代理作为包装来丰富原始行为,即添加事务功能。

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. 在第一种情况下(原来的对象实现的至少一个接口)反射API的动态代理功能用于创建实现与原始对象,因此,代理可以用来代替相同的接口的代理对象。

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. 在第二种情况下(原来的对象没有实现任何接口),因此必须使用更精细的特技,这是CGLIB出现时。 According to the project page "CGLIB is used to extend Java classes and implements interfaces at runtime". 根据项目页面“CGLIB用于扩展Java类并在运行时实现接口”。 So in this case the trick consists on create a proxy that EXTENDS the original object and therefore can be used instead. 因此,在这种情况下,技巧包括创建一个扩展原始对象的代理,因此可以使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM