Issue
I am setting up a bean during the spring boot application startup. I am trying to update the bean using a rest endpoint. The end point in the controller calls the updatePoints(). When I retrieve the data using GET point it still has only the data that was instantiated during the startup. It does not have the updated data inside the bean.
@Component
public class DynamicEntry{
private Map<String, DynamicPoint> dynamicPoints = new HashMap<>();
private DefaultListableBeanFactory beanFactory;
@Autowired
public DynamicEntry(DefaultListableBeanFactory beanFactory){
this.beanFactory = beanFactory;
}
@PostConstruct
void loadPoints(){
//load the dynamicPoints after the spring boots up
}
void updatePoints(String point){
try {
if (!dynamicPoints.containsKey(point)) {
DynamicPoint dynamicPoint = new DynamicPoint(point);
beanFactory.registerSingleton(point, dynamicPoint);
dynamicPoints(point, dynamicPoint);
}
} catch (Exception | Error e) {
e.printStackTrace();
}
}
@Bean
public Map<String, DynamicPoint> dynamicPoints() {
return dynamicPoints;
}
}
Solution
You can try refreshing with ConfigurableApplicationContext.refresh()
:
beanFactory.registerSingleton(point, dynamicPoint);
beanFactory.refresh();
but there will be side effects, e.g. recreation of existing singletons which may lead to your application downtime or response not being sent back to client.
What you are trying to achieve is very non standard. By design singleton bean definitions are processed during startup. You should rethink your approach and don't create singleton beans on the fly. Maybe you need a request or session scoped bean?
Answered By - Karol Dowbecki