java - 从 1.4.2 升级后,Spring Boot 1.4.3+ 中的 LoadTimeWeaving 不起作用

标签 java spring spring-boot load-time-weaving

我有一个启用了 LoadTimeWeaving 的 Spring Boot 项目。当我告诉 Gradle 使用 Spring Boot 1.4.3(或更高版本)而不是 1.4.2 时,应用程序无法再启动,并给出以下形式的错误:

Error starting ApplicationContext. [...] Caused by: java.lang.NoSuchMethodError: [path.to.entity.or.entity.super.class]._persistence_set(Ljava/lang/String;Ljava/lang/Object;)V

_persistence_set 也可以是 _init() 或其他。

据我了解,异常仅意味着实体(或实体的父类(super class))未正确编织,因此无法调用应编织到类中的方法(如 _persistence_set()、_init() 等)。

我使用参数 -verbose:class 来启动我的项目,然后在加载时打印每个类。结果,在 Spring Boot 1.4.2(一切正常)中,实体在 LoadTimeWeaver 初始化之后加载,而在 Spring Boot 1.4.3+ 中,多个抽象基实体类在该点之前加载。这意味着它们在加载时不会被编织,因为编织器尚未初始化,但它们在编织器初始化后不会被编织,因为它们只被加载一次。

现在还不清楚为什么这些基实体类在编织器初始化之前突然加载。有想法吗?

最佳答案

我花了几天时间尝试解决这个问题。这是我在调试 spring 如何初始化应用程序上下文(以及 beans、weaver 等)后发现的。

我们有一些 @Configuration 类,它们定义了使用实体键入的 @Bean。像这样:

@Configuration
public class UserModuleConfiguration {

    @Bean
    public BasePresenter<EUser> userPresenter() {
        return new BasePresenter<EUser>() {
        };
    }
}

当我从该方法的返回类型中删除实体时,一切正常。请注意,由于这些配置中有不止一种为不同的实体提供 BasePresenter,因此您必须使用 @Qualifier 或仅以其自身的权限实例化它们。像这样的事情:

@Configuration
public class UserModuleConfiguration {

    @Bean("userPresenter")
    public BasePresenter<?> userPresenter() {
        return new BasePresenter<EUser>() {
        };
    }
}

@Component
public class UserPresenter<EUser> extends BasePresenter{

}

在内部,在开始“评估”配置之前,spring 正在确定哪些 bean 可用,以确定是否必须加载特定配置(请参阅@ConditionalOnMissingBean 等),并且显然在执行此操作的过程中 spring 加载了实体的一些父类(super class)。我只是想把它留在这里,因为我真的没有发现任何可能的原因,而且我花了很长时间才找到它。

关于java - 从 1.4.2 升级后,Spring Boot 1.4.3+ 中的 LoadTimeWeaving 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52164669/

相关文章:

java - Guava :值或空集的不可变集

java - 使用 FileSystemXmlApplicationContext 编译 Spring Application 时出现 NoSuchMethodError

javascript - 不支持请求方法 'PUT'

java - 将 Spring Boot war 文件部署到 Tomcat 结果为 404,本地主机工作正常

java - Spring boot应用程序中的自定义异常失败

java - 如何以干净的方式在spring-boot中验证基于另一个属性?

java相当于unsigned long long不就是BigInteger吗?

java - 通过unix运行Java GUI程序

java - 隐藏显示 jframe 上的单选按钮

java - 为什么 Map.put() 会覆盖已经存在的键/值对中的现有值?