Why does Spring Boot refresh the context right after preparing the context - java

I am reading the source code of Spring Boot and I found that Spring Boot refreshes the context right after preparing the context in the run method.
SpringApplication.run method:
...
prepareContext(context, environment, listeners, applicationArguments,printedBanner);
refreshContext(context);
...
Can anyone explain why refreshing context is needed? Thanks.

Because refreshContext causes context initialization/reinitialization, such as invoking BeanFactoryPostProcessor beans, registering listeners, initilizing message source etc. You can see it in sources of the AbstractApplicationContext#refresh method.
Here you can find an article about Spring internals and refresh process.

Related

Togglz application context listener warning

I've implemented a basic togglz setup using Spring Boot starter. I'm getting the following at startup:
WARN o.t.s.l.TogglzApplicationContextBinderApplicationListener - ApplicationContext already bound to current context class loader, releasing it first
This may also be causing multiple startups, as I sometimes see the Spring banner go by twice.
To summarize my implementation:
Using property-based toggles in application.yml
Wiring FeatureManager into components
Have a configuration which returns a SpringSecurityUserProvider bean
Not using a TogglzConfig (though I tested with it, and see no difference)
I've looked at the Togglz class, and see the log warning, but I don't understand what situation in Spring Boot would cause this error.
Thank you!

What events triggers actions on Spring BeanFactory?

I have not been able to find much documentation on what sort of events can cause the BeanFactory to be recycled/cleared.
This is my scenario:
I have created a set of beans at runtime.
I am able to use the beans created at runtime with no problem.
I can "re-create" an existing bean which overrides the existing bean. By calling the following code:
((DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory()).registerBeanDefinition("existingBean", builder.getBeanDefinition());
The answer I am looking for is a set of events that can cause the beans that I have created at run time to be cleared or recycled.
For example I know this:
On Container shutdown my beans will be destroyed.
On Container restart my beans will be destroyed.
...
...
What are the other events?
More info..
Running JDK 1.8 with Tomcat 7.
Spring 4.5
I can see my beans by debugging in this manner:
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
beanFactory.getBean("someBean");
If I inspect beanFactory object -> beanDefinitionMap -> table.
Then I can see all the beans created within the context of my web application.
I am trying to determine if there may be other scenarios that I am not aware of, that could lead my beans to dissapear over some point in time.

Spring bean reload with Archaius

I'm trying to use Archaius with my Spring application to reload dynamic system properties without having to do a full restart of the application. I'm planning on implementing this using Archaius' callback mechanism. Once Archaius detects a change, in the callback method I plan to do a bean refresh to pick up the new property changes.
The problem is, there are a few singleton beans that are created on start-up which are using the property I want to reload. I also have a few classes which autowires this singleton bean.
Is there a way of doing a refresh of the bean and all its dependencies without perform a restart or an applicationContext.refresh()?
Or does Archaius have a built-in library which can help with Spring integration?

Implementing servlet lifecycle methods in a Spring web application?

I am implementing a web application using Spring. I am using Spring's ContextLoaderListener, to load up my application contexts, and Spring's DispatcherServlet, to load the relevant beans from {name}-servlet.xml, which refer to the beans in the main application context. I want to be able to integration test these Spring configurations outside of the container to validate everything is wired up correctly before I deploy to Tomcat. However my application requires some scheduled background processing when running in the container. In a regular HttpServlet I would simply implement init() and destroy(). All the suggestions I have read suggest using an InitializingBean for that kind of initialization.
However, if I use an InitializingBean, afterPropertiesSet() gets called whether I am inside the container or in integration tests - and outside the container, I don't have access to the resources that background task needs. Is there a better way to perform the tasks I would normally perform in init() and destroy() so that they will only run when deployed as a webapp?
Have you considered using a test spring config file that overrides the bean implementing your background process?
This way everything else in the spring configuration would work normally except for the one overridden bean.

Can I dynamically load additional Spring configuration files into an existing WebApplicationContext?

Upon starting my webapp within Tomcat 6.0.18, I bootstrap Spring with only what is necessary to initialize the system -- namely, for now, database migrations. I do not want any part of the system to load until the migrations have successfully completed. This prevents the other beans from having to wait on the migrations to complete before operating, or even instantiating.
I have a startup-appcontext.xml configured with a dbMigrationDAO, a startupManager which is a ThreadPoolExecutor, and lastly, a FullSystemLauch bean. I pass a list of configuration locations to the FullSystemLaunch bean via setter injection. The FullSystemLaunch bean implements ServletContextAware, gets a reference to the current WebApplicationContext and thus I can have a ConfigurableListableBeanFactory. Unfortunately, this bean factory isConfigurationFrozen() returns true, so by calling beanFactory.setConfigLocations(configLocations) has no effect.
Can I accomplish this or is Spring preventing me from doing so because it's a bit out of the ordinary? It seems reasonable if understood, but also a bit dangerous. And yes, I'm willing to blow away the current context b/c the currently loaded Singletons are not needed once initialization is complete.
Thank you for the help.
My opinion would be to allow Spring to initialise your beans is it sees fit - in the order of their declared dependencies.
If you need database migrations there are a couple of patterns to have them run first:
if you're using Hibernate/JPA make your sessionFactory/persistenceManager depend-on the migration beans;
if you're using plain JDBC create a wrapper DataSource and in its init-method invoke the migrations ( code sample)
The advantage is clear: simplicity.
You could use the existing context as parent context for the other contexts, although I doubt that you could replace the existing WebApplicationContext.
If you use EAR - WAR packaging, you get this out-of-the-box (sort of) by loading an application context from the EAR and then adding one in the WAR.
Not sure whether this is applicable in your situation.
Could lazy-initialization be an alternative for what you are trying to achieve?
Possible XmlBeanDefinitionReader can help you?
you can upcat the WebApplicatonContext to ConfigurableWebApplicationContext
then use the setConfigurations method.
dont forget refresh;
There was the same task and I created two contexts: startUpContext.xml and applicationContext.xml. In startUpContext.xml there is a bean, which triggers loading of appliationContext.xml. (application context location is configured in startUpContext.xml as a property of a trigger). And finally the trigger replaces locations of the current context and refreshes it:
applicationContext.setConfigLocations(locations);
applicationContext.refresh();
(startUpContext.xml is loaded with a standard spring context loader listener)

Categories