我有一个启用了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之前突然加载这些基本实体类。想法?
答案 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的过程中会加载一些实体的超类。我只是想把它留在这里,因为我真的没有发现任何可能的原因,这花了我很多年的时间。