14

Is it possible to reinitialize a Spring Bean on runtime?

My Bean uses static settings which in some cases changes and then i have to reinitialize the bean.

Fip
  • 323
  • 1
  • 2
  • 10
  • 1
    You can access the bean from context right, and then just create a method `update` inside the bean class, which you can call based on your trigger to update the bean. – Amith Kumar Jul 06 '18 at 22:04
  • My bean is a function inside a configuration class. Does a update function works for this constilation? – Fip Jul 06 '18 at 22:34
  • Yes even if you create bean from a method, it is still an object inside spring context and can be accessed like any other bean. – Amith Kumar Jul 06 '18 at 23:01

1 Answers1

17

You have three options to update singleton bean in spring context, you can chose one suitable for your use case:

Reload method In the Bean
Create a method in your bean which will update/reload its properties. Based on your trigger, access the bean from spring context, and then call the reload method to update bean properties (since singleton) it will also be updated in spring context & everywhere it is autowired/injected.

Delete & Register Bean in Registry
You can use DefaultSingletonBeanRegistry to remove & re-register your bean. The only drawback to this, it will not refresh/reload old instance of already autowired/injected bean in consumer classes.

DefaultSingletonBeanRegistry registry = (DefaultSingletonBeanRegistry) context.getBeanFactory();
registry.destroySingleton({yourbean}) //destroys the bean object
registry.registerSingleton({yourbeanname}, {newbeanobject}) //add to singleton beans cache

@RefreshScope
Useful for refreshing bean value properties from config changes. But it has very limited & specific purpose. Resource to read more about it.

Amith Kumar
  • 3,321
  • 1
  • 10
  • 17
  • It's so hard to reload properties. – Alex78191 Mar 18 '19 at 17:55
  • Why not just `bean = applicationContext.getBean(Bean.class)`? – Alex78191 Mar 18 '19 at 18:23
  • 2
    Because it will just get you the already loaded bean from the context, and not refresh/reload it. I don't understand when you say, it's so hard ? – Amith Kumar Mar 18 '19 at 18:26
  • Create a public init method to reload all properties, use the same in constructor & reload call. – Amith Kumar Mar 18 '19 at 18:36
  • 2
    In my case new bean is returned on `applicationContext.getBean(Bean.class)`. It's because of `@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)`. – Alex78191 Mar 18 '19 at 18:47
  • 2
    Yeah this question doesn't apply for non-singleton beans. Prototype scope is per use, so your bean is created new for every demand, so no question of reloading applies. – Amith Kumar Mar 18 '19 at 20:07
  • I have tried to fetch the DefaultSingletonBeanRegistry from the ApplicationContext `DefaultSingletonBeanRegistry registry = (DefaultSingletonBeanRegistry) context.getBeanFactory();` the `context` object is of type `ApplicationContext` but I got the following error `The method getBeanFactory() is undefined for the type ApplicationContext` And also suggests `change to getParentBeanFactory(..)` Help is much appreciated – Kokkonda Abhilash Jun 22 '20 at 03:52