繁体   English   中英

重新初始化spring @Autowire bean

[英]Reinitialize spring @Autowire bean

我有一种情况,我需要在启动期间根据应用程序配置来初始化bean。 后来,由于基于事件获取了动态配置,因此我必须更新Bean。

该bean无法更新,只能用新实例替换。

使用new运算符是否仅初始化本地实例,还是会更改Bean?

@Component
public class TestComp {

  @Autowired
  private BeanA beanA;

  public void updateBean() {
    beanA = new BeanA("new value");
  }

}

我在另一个类中引用了该bean,并在用new初始化它之后进行了检查。 它反映了新对象。 但是,如果需要,我需要得到专家的确认。

我有一种情况,我需要在启动期间根据应用程序配置来初始化bean。

没关系。 在这里,单例作用域是一个不错的选择。

后来,由于基于事件获取了动态配置,因此我必须更新Bean。

这是一个问题。 在上下文中更新bean是一个复杂的过程:您需要删除现有的bean定义,添加一个新的bean定义,并更新与该bean某种程度上相关的所有bean(重新初始化这些组件,刷新上下文)。 从技术上讲,这是可能的,并且已通过Spring Cloud的@RefreshScope进行了简化。

使用new运算符仅初始化本地实例还是会更改Bean?

它仅影响此类中的字段。 没有人知道这一变化。 ApplicationContext#getBean仍将返回旧对象,并且所有组件都将(或已经)用旧实例初始化。

我在另一个类中引用了该bean,并在用new对其进行初始化之后进行了检查。 它反映了新对象。

不可能是真的 可能是它引用了TestComp#beanA字段,而不是它自己的BeanA字段。

我建议的解决方案是根据收到的事件定义自定义bean范围 它将保持Bean和上下文的更新。

这听起来像你想有一个工厂来代替 下面是大概的样子。 您的需求可能会有所不同。

@Component
public class BeanFactory {
    private volatile BeanA beanAInstance;

    public BeanA createBeanA(String value) {
        if (null == beanAInstance) {
            synchronized (this) {
                if (null == beanAInstance) {
                    beanAInstance = new BeanA(value);
                }
            }
        }
        return beanAInstance;
    }

    public void refreshBeanA(String newValue) {
        synchronized (this) {
            beanAInstance = new BeanA(newValue);
        }
    }
}

然后将其连接起来,然后根据配置,可以刷新并使用新值。 请记住,这将改变您从该bean获得的价值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM