Java Spring重新创建特定的Bean [英] Java Spring Recreate specific Bean

查看:572
本文介绍了Java Spring重新创建特定的Bean的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to re-create (new Object) a specific bean at Runtime (no restarting the server) upon some DB changes. This is how it looks -

@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();
    }
}

该代码无法运行,因为myShop对象是由Spring以Singleton&除非重新启动服务器,否则其上下文不会刷新.如何刷新(创建新对象)myShop?

This code does not run as myShop object is created by Spring as Singleton & its context does not get refreshed unless the server is restarted. How to refresh (create a new object) myShop ?

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

One bad way I can think of is to create new myShop object inside restartListeners() but that does not seem right to me.

推荐答案

在DefaultListableBeanFactory中,您可以使用公共方法destroySingleton("beanName"),以便可以使用它,但是您必须知道,如果将您的bean自动接线,它将保留与最初自动装配的对象相同的实例,您可以尝试执行以下操作:

In DefaultListableBeanFactory you have public method destroySingleton("beanName")so you can play with it, but you have to be aware that if your autowired your bean it will keep the same instance of the object that has been autowired in the first place, you can try something like this:

@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,因为它已从上下文中删除,所以我想知道它是否仍然存在,或者是否在控制器中释放了它,是否进行了垃圾收集?上面的内容,如果上下文中的其他一些对象引用了它,则上面的内容会引起问题.

It is not pretty but shows how you can approach it. If you were dealing with a controller rather than a component class, you could have an injection in method argument and it would also work, because Bean would not be recreated until needed inside the method, at least that's what it looks like. Interesting question would be who else has reference to the old Bean besides the object it has been autowired into in the first place,because it has been removed from the context, I wonder if it still exists or is garbage colected if released it in the controller above, if some other objects in the context had reference to it, above would cause problems.

这篇关于Java Spring重新创建特定的Bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆