【问题标题】:Spring application has Cglib2AopProxy warningsSpring 应用程序有 Cglib2AopProxy 警告
【发布时间】:2024-05-21 09:35:01
【问题描述】:

在启动我的应用程序时,我收到了许多类似于o.s.aop.framework.Cglib2AopProxy 'Unable to proxy method [public final void org.springframework.jdbc.core.support.JdbcDaoSupport.setDataSource(javax.sql.DataSource)] because it is final: All calls to this method via a proxy will be routed directly to the proxy.' 的警告,涉及大约十几个功能。

现在我完全明白基于代理的方面不能应用于最终方法。但是,我没有(至少是故意的)尝试将任何方面编织到JdbcDaoSupport 中。我怀疑它来自<tx:annotation-driven />。我可以做些什么来消除这些警告,或者更好的是,将这些类从方面编织中排除?

【问题讨论】:

    标签: spring spring-aop spring-transactions


    【解决方案1】:

    这很可能是由 @Transactional 注释引起的,Spring 将您的 DAO 包装在代理中以添加事务行为。

    我建议让你的 DAO 实现一个接口(为你的 DAO 创建和使用一个接口),这将允许 Spring 使用 JDK 动态代理,而不必使用 CGLib。 p>

    使用 CGLIB 有一个限制,即不能建议在目标类中标记为 final 的方法,因为最终方法不能被覆盖(CGLIB 在运行时创建目标类的子类),但是在使用 JDK 动态的情况下,这个限制就会消失代理。

    Reference

    【讨论】:

    • 我很清楚代理问题,如问题中所述。但是,我不在任何地方使用JdbcDaoSupport。我所有的存储库(除了一个)都使用 Spring Data,因此无论如何都必须是接口。我必须研究剩下的一个是罪魁祸首还是 Spring Data 本身,或者可能是扩展其中之一的自定义实现。
    【解决方案2】:

    也许你已经扩展了JdbcDaoSupport 并添加了@Transactional 注释。

    您可以将 Cglib2AopProxy 记录器设置为日志级别 ERROR 以避免警告消息。例如,如果使用 log4j 和 log4j.properties:

    log.logger.org.springframework.aop.framework.Cglib2AopProxy = ERROR
    

    【讨论】:

    • 以这种方式静音它有点太不具体了。警告本身可能很有帮助。
    【解决方案3】:

    您应该使用接口进行依赖注入,其中的大部分原因都在herehere 中进行了描述。

    您可以阅读documentation about proxying mechanic,详细了解您看到此警告的原因。

    请为feature request of inspection for IntelliJ 投票,这可能有助于我们避免此警告。顺便说一句,它还包含一个很好的解释。

    【讨论】:

    • 我不同意“你应该使用接口进行依赖注入”,你引用的引用来自2012年。
    【解决方案4】:

    Spring Boot 现在默认使用 CGLIB 代理,包括 AOP 支持。如果需要基于接口的代理,则需要将 spring.aop.proxy-target-class 设置为 false。

    spring.aop.proxy-target-class=false

    【讨论】: