将 weblogic spring 网络应用程序转换为 spring 引导应用程序时出现 CGLIB 错误

CGLIB errors converting a weblogic spring web app to springboot app

我正在尝试将现有的 spring weblogic 应用程序转换为 spring 引导嵌入式 tomcat 应用程序。

有很多移动部分,因此很难显示任何代码,我希望有一些通用的答案可以让我了解这个问题。

在 weblogic 下,使用 spring-framework 4.3.6.RELEASE 库,应用程序部署良好。创建不同的服务、存储库和组件 bean 没有问题。

但是,当我将其迁移到 Spring Boot 1.5.1.RELEASE 时,出现以下错误:

2017-06-21 17:08:16,402 [ERROR] SpringApplication reportFailure (815) - Application startup failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'alertEventServiceImpl': Unsatisfied dependency expressed through field 'alertEventDao'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'alertEventDaoImpl' defined in URL [jar:file:/Users/username/Development/source/carma-war/target/carma-war-2.0.0-SNAPSHOT.war!/WEB-INF/lib/protocol-manager-1.8.0-SNAPSHOT.jar!/org/ihc/hwcir/protocol/dao/AlertEventDaoImpl.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class org.ihc.hwcir.protocol.dao.AlertEventDaoImpl]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class org.ihc.hwcir.protocol.dao.AlertEventDaoImpl

我们的许多服务 类 是 最终版本,因为它们不应被扩展。由于有太多是最终的,我想尽量减少我们为使这项工作而修改的不同库中的代码量。

我认为因为 bean 创建过程在 weblogic 下工作,所以它应该在 spring 引导下工作。

我试图强制不使用 cglib 代理的事情:

  1. 所有实现都已经实现了接口
  2. 在通过 xml 创建的 bean 中,添加了 <aop:scoped-proxy proxy-target-class="false"/>
  3. 在通过注释创建的 bean 中,添加(服务 bean 的示例)

@Service @Scope(proxyMode = ScopedProxyMode.INTERFACE)

但是,最后我很困惑,为什么spring可以在weblogic容器下创建bean(类标记为final),而在嵌入式tomcat spring-引导容器。

Spring 引导默认使用基于 class 的代理,不适用于 final classes/methods。

要禁用此功能,请将 spring.aop.proxy-target-class=false 添加到 application.properties 以启用 JDK 动态代理而不是基于 class 的代理。 (并还原您的修改)。

注意: 要让所有内容都考虑到 spring.aop.proxy-target-class 您可能需要升级到 Spring Boot 1.5.3 作为一些最终补丁将此 属性 包含在以前版本中遗漏的部分中。

有关详细信息,请参阅以下问题 8434, 8869 and 8887

我无法使用 M. Deinums 的回答使用 spring.aop.proxy-target-class=false 来完成这项工作。

对我有用的是在 application.properties 文件中添加

spring.dao.exceptiontranslation.enabled=false

请注意,此选项会禁用存储库的代理创建。

并且在我的 spring 引导应用程序配置器中注释处理事务而不使用代理 class。

@EnableTransactionManagement(proxyTargetClass = false)

这是使用 Spring 引导版本 1.5。1.RELEASE。