在春季AOP中使用代理

2022-09-01 18:08:21

我正在读一本书,其中谈到了在春季AOP中启用AspectJ支持。

下面给出的是书中的一段话:

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

对于接口不可用或未在应用程序设计中使用的情况,可以通过依赖 CGLIB 来创建代理。要启用 CGLIB,您需要在 <aop:aspectj-autoproxy /> 中设置属性 proxy-target-class=true


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


答案 1

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

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

这是强制创建 CGLIB 代理的方法(设置代理-目标-类=“true”):

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

使用AspectJ及其自体填充支持时,您还可以强制使用CGLIB代理。这是使用 的地方,在这里,“代理目标类”必须设置为 true<aop:aspectj-autoproxy>

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

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


答案 2

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

例如,假设我有一个接口MyService

public interface MyService {
    void doSomething();
}

和实现MyServiceImpl

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

如果 Spring 发现您已经为 配置了方面,它将创建一个 JDK 代理,该代理实现并代理对 Bean 的所有调用,并在适当的时候添加方面功能。MyServiceMyServiceMyServiceImpl

JDK代理的工作原理是实现与目标对象相同的接口,并将调用委派给它;如果没有要实现的接口,它们就不起作用。如果您没有像上面这样的接口,Spring需要使用像CGLIB这样的字节代码库在运行时动态创建包含方面功能的类。


推荐