当前位置: 首页 > 知识库问答 >
问题:

Spring AOP什么时候使用CGLIB代理?

宰父俊彦
2023-03-14

我在读一些关于Spring AOP的文章,遇到了这样的情况:

AOP代理:由AOP创建的对象,用于实现方面契约。在Spring中,代理对象可以是JDK动态代理或CGLIB代理。默认情况下,代理对象将是JDK动态代理,被代理的对象必须实现一个接口,该接口也将由代理对象实现。但是像CGLIB这样的库也可以通过子类创建代理,因此不需要接口。

您能否看看下面的结构,并想象一下我们想要建议bar()方法。

public interface Foo {
    void foo();
}

public class FooImpl implements Foo {

    @Override
    public void foo() {
        System.out.println("");
    }

    public void bar() {
        System.out.println("");
    }

}

共有1个答案

孙恩
2023-03-14

Spring只会使用CGLIB,如果您告诉它这样做。通过将@EnableAspectJAutoproxyProxyTargetClass元素设置为true来启用(对于基于注释的配置)。

@EnableAspectJAutoProxy(proxyTargetClass = true)

考虑这个最小的示例(假设您的fooimpl@component注释)

@Aspect
@Component
class FooAspect {
    @Before("execution(public void bar())")
    public void method() {
        System.out.println("before");
    }
}

@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class Example {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Example.class);
        FooImpl f = ctx.getBean(FooImpl.class); // throw exception here
        f.bar();
    }
}

默认情况下,ProxyTargetClassfalse。在这种情况下,Spring不会使用cglib。由于@Aspect类中的@before建议,Spring将决定它需要使用JDK代理来代理fooimpl。不幸的是,由于这种代理行为,实际存储在上下文中的bean将是动态JDKproxy类型(也是foo接口的子类型),因此尝试使用fooimpl.class获取bean将失败。

即使您试图将其作为foo检索,也无法调用bar()方法,因为代理对象不是fooimpl

如果启用ProxyTargetClass,则上面的代码将按预期工作,创建一个CGLIB代理,并调用@before建议。

 类似资料:
  • 问题内容: 奇怪的是: 似乎或多或少被定义为。通过这种方式很容易产生错误: 一些fname意外地以else块结尾。修复很简单,我们应该改用它,但是从表面上看,这似乎是一种不错的pythonic方式,并且比“正确”的方式更具可读性。 由于字符串是不可变的,所以为什么字符串错误是什么技术细节?什么时候进行身份检查更好,什么时候进行平等检查更好? 问题答案: 据我所知,检查对象身份是否相等。由于没有强制

  • 问题内容: 我有一个将客户发送到另一个站点来处理付款的应用程序。客户之外的另一个站点在我们的服务器上调用一个页面,让我们知道付款的状态。被调用页面会检查付款应用程序提供的参数,并检查我们是否知道该交易。然后,它更新数据库以反映状态。这一切都无需与客户进行任何互动即可完成。 我个人选择将此功能实现为JSP,因为将文件拖放到文件系统中比编译和打包文件然后将条目添加到配置文件中要容易得多。 考虑到页面的

  • 问题内容: 我怎么能说: 为什么函数调用中不需要括号,而最后一行呢? 问题答案: 是一个功能 调用该函数并产生该函数返回的任何值。 setTimeout的目的是在一段时间后运行代码。你需要的功能只是传递给它(这样的setTimeout可以自称在适当的时候函数),因为如果你将它传递给setTimeout的前调用的函数(用括号),将执行 现在 而不是1秒后,。

  • 一般来说,当发现 CPU 的占用率和实际业务应该出现的占用率不相符,或者对 Nginx worker 的资源使用率(CPU,内存,磁盘 IO )出现怀疑的情况下,都可以使用火焰图进行抓取。另外,对 CPU 占用率低、吐吞量低的情况也可以使用火焰图的方式排查程序中是否有阻塞调用导致整个架构的吞吐量低下。 常用的火焰图有三种: lj-lua-stacks.sxx 用于绘制 Lua 代码的火焰图 sam

  • 问题内容: 我习惯于进行Java编程,在编程时,您无需真正考虑指针。但是,此刻我正在用C ++编写程序。在创建具有其他类成员的类时,何时应该使用指针,何时不应该使用指针?例如,什么时候我想这样做: 与此相反: 问题答案: 首先避免指针。 在以下情况下使用它们: 您想使用Pimpl习惯用法或抽象工厂。 该实例实际上是由程序的其他部分管理的,而该类仅需要能够访问它。 您想推迟对象的构建(即,您想 在

  • 本文向大家介绍什么时候用delegate,什么时候用Notification?相关面试题,主要包含被问及什么时候用delegate,什么时候用Notification?时的应答技巧和注意事项,需要的朋友参考一下 答:delegate针对one-to-one关系,并且reciever可以返回值 给sender,notification 可以针对one-to-one/many/none,recieve