从1.4.2升级后,Spring Boot 1.4.3+中的LoadTimeWeaving无法正常工作

时间:2018-09-04 10:55:14

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

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

  

启动ApplicationContext时出错。 [...]   造成原因:java.lang.NoSuchMethodError:[path.to.entity.or.entity.super.class] ._ persistence_set(Ljava / lang / String; Ljava / lang / Object;)V

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

据我所知,该异常仅表示该实体(或实体的超类)未正确编织,因此无法调用应编织到该类中的方法(例如_persistence_set(),_ init( )等。

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

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

1 个答案:

答案 0 :(得分:0)

我试图解决这几天。这是在调试spring如何初始化应用程序上下文(以及Bean,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的过程中会加载一些实体的超类。我只是想把它留在这里,因为我真的没有发现任何可能的原因,这花了我很多年的时间。