Java Spring重新创建特定的Bean

发布于 2021-01-30 16:25:29

我想在某些数据库更改后在运行时重新创建(新对象)特定的Bean(不重新启动服务器)。看起来就是这样-

@Component
public class TestClass {

    @Autowired 
    private MyShop myShop; //to be refreshed at runtime bean

    @PostConstruct //DB listeners
    public void initializeListener() throws Exception {
        //...
        // code to get listeners config
        //...

        myShop.setListenersConfig(listenersConfig);
        myShop.initialize();
    }

    public void restartListeners() {
        myShop.shutdownListeners();
        initializeListener();
    }
}

此类代码不会运行,因为myShopSpring是由Singleton创建的对象,除非重新启动服务器,否则其上下文不会刷新。如何刷新(创建一个新对象)myShop

我想到的一种不好的方法是在myShop内部创建新对象,restartListeners()但这对我来说似乎不对。

关注者
0
被浏览
129
1 个回答
  • 面试哥
    面试哥 2021-01-30
    为面试而生,有面试问题,就找面试哥。

    在DefaultListableBeanFactory中,您具有公共方法destroySingleton(“
    beanName”),因此可以使用它,但是您必须知道,如果您自动装配了bean,它将保留最初自动装配的对象的相同实例。可以尝试这样的事情:

    @RestController
    public class MyRestController  {
    
            @Autowired
            SampleBean sampleBean;
    
            @Autowired
            ApplicationContext context;
            @Autowired
            DefaultListableBeanFactory beanFactory;
    
            @RequestMapping(value = "/ ")
            @ResponseBody
            public String showBean() throws Exception {
    
                SampleBean contextBean = (SampleBean) context.getBean("sampleBean");
    
                beanFactory.destroySingleton("sampleBean");
    
                return "Compare beans    " + sampleBean + "=="
    
        + contextBean;
    
        //while sampleBean stays the same contextBean gets recreated in the context
                }
    
        }
    

    它不是很漂亮,但显示了如何实现它。如果要处理的是控制器而不是组件类,则可以在方法参数中进行注入,并且它也可以工作,因为直到在方法内部需要时才重新创建Bean,至少看起来是这样。有趣的问题是,除了首先将其自动连线到的对象外,还有谁还引用了旧Bean,因为已将其从上下文中删除,所以我想知道它是否仍然存在,或者是否在控制器中释放了该对象而进行了垃圾收集上面的内容,如果上下文中的某些其他对象引用了它,则上面的内容会引起问题。



推荐阅读
知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看