Spring Boot 1.4.3+ 中的 LoadTimeWeaving 在从 1.4.2 升级后无法正常工作
LoadTimeWeaving in Spring Boot 1.4.3+ not working after upgrade from 1.4.2
我有一个启用了 LoadTimeWeaving 的工作 Spring 引导项目。当我告诉 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() 或其他东西。
根据我的理解,异常只是意味着实体(或实体的超 class)没有正确编织,因此应该编织到 class 中的方法不能被调用(如 _persistence_set()、_init() 等)。
我使用参数 -verbose:class 来启动我的项目,然后在加载时打印每个 class。结果是 Spring Boot 1.4.2(一切正常)实体在 LoadTimeWeaver 初始化后加载,而 Spring Boot 1.4.3+ 多个抽象基础实体 classes在那一点之前加载。这意味着它们在加载时不会编织,因为编织器尚未初始化,但在编织器初始化后它们不会编织,因为它们只加载一次。
现在还不清楚为什么这些基本实体 classes 在编织器初始化之前突然加载。想法?
我试图解决这个问题好几天了。这是我在调试 spring 如何初始化应用程序上下文(以及 bean、weaver 等)后发现的。
我们有一些 @Configuration 类 定义了用实体键入的 @Bean。像这样:
@Configuration
public class UserModuleConfiguration {
@Bean
public BasePresenter<EUser> userPresenter() {
return new BasePresenter<EUser>() {
};
}
}
当我从该方法的 return 类型中删除实体时,一切正常。请注意,由于这些配置中不止一种为不同的实体提供 BasePresenter,因此您必须使用 @Qualifier 或直接实例化它们。像这样:
@Configuration
public class UserModuleConfiguration {
@Bean("userPresenter")
public BasePresenter<?> userPresenter() {
return new BasePresenter<EUser>() {
};
}
}
或
@Component
public class UserPresenter<EUser> extends BasePresenter{
}
在内部,在开始 'evaluate' 配置之前 spring 正在确定哪些 bean 可用以确定是否必须加载特定配置(请参阅@ConditionalOnMissingBean 等)并且显然在这样做 spring 的过程会加载实体的一些超级 类。我只是想把它留在这里,因为我真的没有发现任何可能的原因,我花了很长时间才找到它。
我有一个启用了 LoadTimeWeaving 的工作 Spring 引导项目。当我告诉 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() 或其他东西。
根据我的理解,异常只是意味着实体(或实体的超 class)没有正确编织,因此应该编织到 class 中的方法不能被调用(如 _persistence_set()、_init() 等)。
我使用参数 -verbose:class 来启动我的项目,然后在加载时打印每个 class。结果是 Spring Boot 1.4.2(一切正常)实体在 LoadTimeWeaver 初始化后加载,而 Spring Boot 1.4.3+ 多个抽象基础实体 classes在那一点之前加载。这意味着它们在加载时不会编织,因为编织器尚未初始化,但在编织器初始化后它们不会编织,因为它们只加载一次。
现在还不清楚为什么这些基本实体 classes 在编织器初始化之前突然加载。想法?
我试图解决这个问题好几天了。这是我在调试 spring 如何初始化应用程序上下文(以及 bean、weaver 等)后发现的。
我们有一些 @Configuration 类 定义了用实体键入的 @Bean。像这样:
@Configuration
public class UserModuleConfiguration {
@Bean
public BasePresenter<EUser> userPresenter() {
return new BasePresenter<EUser>() {
};
}
}
当我从该方法的 return 类型中删除实体时,一切正常。请注意,由于这些配置中不止一种为不同的实体提供 BasePresenter,因此您必须使用 @Qualifier 或直接实例化它们。像这样:
@Configuration
public class UserModuleConfiguration {
@Bean("userPresenter")
public BasePresenter<?> userPresenter() {
return new BasePresenter<EUser>() {
};
}
}
或
@Component
public class UserPresenter<EUser> extends BasePresenter{
}
在内部,在开始 'evaluate' 配置之前 spring 正在确定哪些 bean 可用以确定是否必须加载特定配置(请参阅@ConditionalOnMissingBean 等)并且显然在这样做 spring 的过程会加载实体的一些超级 类。我只是想把它留在这里,因为我真的没有发现任何可能的原因,我花了很长时间才找到它。