Java Spring没有在原型bean中调用@autowiredsetters 问题是:

Java Spring没有在原型bean中调用@autowiredsetters 问题是:,java,spring,spring-boot,kubernetes,autowired,Java,Spring,Spring Boot,Kubernetes,Autowired,问题出现在运行spring boot的k8s pod中,java 8(更多详细信息如下) 当使用ObjectProvider并调用*provider.getObject(…)*时,在 Spring配置中定义的原型bean,时不时(从不 找到一种方法使其定期发生)不调用setter注入方法 10月2日更新:参见 在大多数情况下,它工作得非常好,但有时,它会构造一个新对象 但是没有调用@Autowired setter方法(使用日志信息检查) 我们还发现,90%的情况发生在应用程序启动之后,但并不总

问题出现在运行spring boot的k8s pod中,java 8(更多详细信息如下)

当使用
ObjectProvider
并调用
*provider.getObject(…)*
时,在 Spring配置中定义的原型bean,时不时(从不 找到一种方法使其定期发生)不调用setter注入方法

10月2日更新:参见

在大多数情况下,它工作得非常好,但有时,它会构造一个新对象 但是没有调用@Autowired setter方法(使用日志信息检查)

我们还发现,90%的情况发生在应用程序启动之后,但并不总是这样

9月21日更新:删除(重新启动)反吊舱解决了问题

9月22日更新:一旦发生,它将一直发生,我的意思不是它失败一次,下一次工作正常时,它将始终无法调用setter

9月23日更新:与实际应用程序中的并发问题相关的新证据,直到现在才出现,似乎只有一个线程 产生问题。(请看下面的课程,以便更好地理解 (本说明)

ToipParentClass(这是一个策略实现)具有setter@Autowired for

  • 虚拟社会服务
  • 订单管理服务
InternetParentClass(这是一个策略实施)已将setter@Autowired用于

  • 虚拟社会服务
  • 订单管理服务
日志(已评论)

我在RunIt standalone中做了一个简单的测试,不同的jdk8版本,也在pod中使用的同一个docker映像中(项目中的所有内容),但没有让它失败

关于在哪里寻找问题的想法,关于尝试什么的建议,甚至 一个解决方案:-),将非常受欢迎,提前感谢

下面是产品版本、类别

有关版本的详细信息: k8s:

v1.14.9-eks-658790
2.1.4.RELEASE
  openjdk version "1.8.0_212"
  OpenJDK Runtime Environment (IcedTea 3.12.0) (Alpine 8.212.04-r0)
  OpenJDK 64-Bit Server VM (build 25.212-b04, mixed mode)
弹簧靴:

v1.14.9-eks-658790
2.1.4.RELEASE
  openjdk version "1.8.0_212"
  OpenJDK Runtime Environment (IcedTea 3.12.0) (Alpine 8.212.04-r0)
  OpenJDK 64-Bit Server VM (build 25.212-b04, mixed mode)
JDK:

v1.14.9-eks-658790
2.1.4.RELEASE
  openjdk version "1.8.0_212"
  OpenJDK Runtime Environment (IcedTea 3.12.0) (Alpine 8.212.04-r0)
  OpenJDK 64-Bit Server VM (build 25.212-b04, mixed mode)
班级 一个关于所涉及类的代码片段,没有真正的代码,不必担心语法错误。 (真实代码可在中找到)

//============================================================
公共界面策略{
无效工作(……);
}
// ============================================================
@服务
公务舱服务{
公共无效剂量测定法(){
......
......
}
}
// ============================================================
公共类MobileStategy实现策略{
私人服务;
@自动连线
公共无效设置服务(服务){
this.service=s;//未不时调用setter
}
公共工程(……){
this.service.doSomething();//时不时抛出NullPointerException
}
}
// ============================================================
公共枚举策略枚举{
移动(“mobileKey”,MobileStragey.class),
电视(“tvKey”,TvStrategy.class),
.......
公共类getImplementationClass(){
......
}
公共策略Enum findByKey(字符串键){
.....
}
}
// ============================================================
@配置
公共类配置{
@豆子
@范围(值=ConfigurableBeanFactory.Scope\u原型)
公共战略getStrategy(最终战略Enum SelectorEnm){
试一试{

构造函数这不是在
Configuration#getStrategy
方法中创建
Strategy
bean实例的正确方法,因为它不会使用自动连线调用setter

Constructor<? extends Strategy> constructor =
                selectorEnum.getImplementationClass().getConstructor();

return constructor.newInstance();
我发现的问题 10月1日更新:请阅读问题中的@Denium评论!!!!(谢谢)

在今天(9月23日)的更新之后,问题显然是并发性问题,我能够轻松地重现它(请参阅) 在一个简单的Spring应用程序中,没有Spring引导

使所有策略实施都具有相同的@Autowired setter集 错误仍然存在

似乎已经完成了一些缓存,@Autowired setter是从缓存中获取的,而不是从新构造的对象中获取的,尽管我试图挖掘在如此短的时间内难以理解的spring源代码

问题解决了,避免了并发(如下更改),所以现在我的问题是:

这是预期行为还是错误?

我在任何地方都找不到关于这个问题或描述这个行为的任何文档,所以对我来说仍然是一个问题

我在spring boot版本1.5.22、2.1.4(我们目前使用的)和2.3.4中进行了测试,在所有情况下都会出现相同的问题,只是在一个简单的spring应用程序中,不需要RestController等等

解决方法1 添加一个中间工厂,以确保“同步”创建策略bean

10月1日更新:在@Deinum注释之后,据我所知,Spring每次(或几乎每次)都会扫描类以查找注释,所以我想变通方法2可能是更好的解决方案

此解决方案更适合我当前的环境

新型战略工厂 注意
getStrategy(…)
方法是同步的,我想这是一个解决方案 将对性能产生一定影响,但仍无法衡量

@Component
public class StrategyFactory {

    @Autowired
    ObjectProvider<Strategy> provider;

    public synchronized Strategy getStrategy(final MathOperEnum operation) {
        return this.provider.getObject(operation);
    }

}
解决方法2
  • 使StrategyFactory应用程序具有ContextAware
  • 将@component/@Scope注释添加到每个策略实施中
  • 删除@Configuration类

除了讨论是否应该使用它之外,有一点我可以说,它在99%的情况下都能很好地工作,构造函数.newInstance()在一个@Configuration类中被调用,在一个带有@Bean注释的方法中,在某种程度上等同于执行new WhateverStrategy(),这在配置类中是正常的,可能是我遗漏了什么?不是