Recently, I came into the situation where I needed to reload the Spring Bean instance. Because this bean is using an external yml file which updates sometimes. The requirement is to reinitialize the bean instance after any change in the YML file.
Related
Using Spring Boot 1.5.12, we create scoped proxies for #ConfigurationProperties beans. We do this so that we can effectively have property values that are scoped to the user/session/etc. We use a BeanFactoryPostProcessor to register a scoped proxy created by ScopedProxyUtils.createScopedProxy and change the scope of the target bean definition to our custom scope.
This worked great in Spring Boot 1.5.12. However, in Spring Boot 2, the introduction of the Binder API has made this stop working. This is because when Spring Boot binds #ConfigurationProperties in its ConfigurationPropertiesBindingPostProcessor, it uses Bindable.of(type).withExistingValue(bean) passing in a type (e.g. org.example.Foo) and the bean which is an instance of ScopedProxyFactoryBean. Bindable checks that bean is an instance of type which it's not and things blow up.
Does anyone know of a general way to accomplish this? Specifically, to replace the #ConfigurationProperties bean definition with a proxy while still allowing the properties to bind to the instance? I've considered delaying the creation of the proxy until after the target has already been bound by ConfigurationPropertiesBindingPostProcessor (i.e. in my own BeanPostProcessor). However, at this point the bean is instantiated and my proxy can only replace the bean. It can't really leave the original bean in the context as a target. So I'm struggling with how to do this using a BeanPostProcessor.
EDIT: I've created a simple example project that demonstrates the issue (with the ability to check out code that works on Spring Boot 1 and fails on Spring Boot 2).
I have an annotation-configured Spring web app, I need to alter bean creation order to define what is the very first bean loaded during context boot up.
Is it possible without switching to xml configuration?
I have an existing MVC web application.
Part 1: Is it possible to reload a bean with some changes to the source code with out refreshing the application context?
or,
If I load a class using my custom class loader, will that be managed by spring container? Or can I do anything that it could be managed by Spring container?
Part 2: Is it possible to copy field values from old bean to new bean during class reloading?
Is there a way to update a Spring bean dynamically if the spring beans configuration changes?
E.g. assume that I have a spring bean with boolean property x and the spring beans has the value true when the application starts.
So spring creates the bean with the property x set to true.
Is there a way so that if I changes the property to x (while the application is running) that the property will be updated e.g. to false?
Calling the setter for x setX() method will do that.
But it should not be a prototype bean.
it is possible with the jrebel-spring integration. it monitors your configuration and TRIES to re-wire your beans at runtime.
Though i would not use it in production...only for playing around, testing etc
Spring reads configuration files at startup. If you really need to update configs while application running, you should manually implement all the chain: detecting config changes, validating config, detecting changed beans, updating beans in context.
Spring beans can be initialized using applicationContext.xml or even programatically. In your case; you will need to remove configurations from xml and add into java program. You can get some idea from How to programmatically create bean definition with injected properties? . Other good links were also available on google.
When you create a Service bean or Dao bean in your Spring applicationContext.xml file, what is the scope of those beans?
Will every person who accesses the web application use the same instance of the bean, or is the bean instantiated for each user's session?
By default a bean created in Spring is of scope singleton, so yes each person will access the same instance in those cases. The alternative is to specify the scope as prototype.
More info on this here, sections 3.4.1 and 3.4.2:
http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-factory-scopes-prototype
By default a bean created in Spring is of scope singleton. However, if you use Spring DispatcherServlet and DispatcherPortlet, a bean scope is requested.