Prevent Spring from Failing if One Bean Fails - java

We have an application that creates beans on startup using Spring's AnnotationConfigApplicationContext. What we're trying to do is not have Spring destroy all the beans created and thus cause the app fail on startup if creation of one of the beans fails. Is there any native Spring config or way to accomplish this?
I tried overriding the AnnotationConfigApplicationContext with my own Custom AnnotationConfigApplicationContext and catching exceptions within there. What was happening though is when an exception was thrown, all remaining beans were not created.
We're using Spring 4.3.0.

easy way to deal with this is by lazy initialization of bean using attribute lazy-init="true" in your bean declaration

Related

Programmatic run-time injection/auto-wiring in quarkus

I am looking for a a way to do runtime injection of a bean in Quarkus. I realize this might be a bit on an unorthodox approach for quarkus, and something on an anti-pattern, so no need to point that out, I am fully aware :)
What I am looking for is a way to construct a bean during runtime, and having any annotated properties injected from the Quarkus context.
In Spring Boot I would get the application context by having a bean initialized normally by spring boot, using the ApplicationContextAware interface to inject the application context. I would then use that as a factory by calling ApplicationContext.getAutowireCapableBeanFactory() to get the auto-wire factory and using the autowireBean method on the factory to autowire my beans during runtime. I am wondering if something similar is possible in Quarkus?
This is similar to this question.
How to programmatically inject a Java CDI managed bean into a local variable in a (static) method
javax.enterprise.inject.spi.CDI.current().getBeanManager().select(C.class).get()
To make sure that the bean class is manged use the io.quarkus.arc.Unremovable annotation.

Modify application context in TestExecutionListener before Spring Boot autoconfiguration phase

Is there a way to modify the application context in a TestExecutionListener (or anywhere else) before Spring Boot's autoconfiguration is ran?
I would like to register a specific bean in my test context so that Spring Boot doesn't autoconfigure its own (because of #ConditionalOnMissingBean), but in some cases would like to remove the registered bean so that the autoconfig kicks in (because of the missing bean condition).
Or maybe there is another way to force a specific autoconfig to load? Although this is somewhat less desirable because it wouldn't exactly match how it works in production.

Spring Application Failure

I have a Spring Boot app with many beans. In one bean, if there is an exception in the bean's constructor, the application fails to start. In a different bean, an exception in the constructor does not cause the application to fail to start. Failing to start is the desired behavior. What is the difference between the two beans? How do I get the behavior to be the same?

How do I lazily register Spring 'bean definitions' in order to improve startup time?

Our Java Web application loads with over 1000 plugins that are all registered by us as Spring beans using the ApplicationContext#registerBeanDefinition() method. These beans often have other dependencies which we also register as spring beans using the same method (for a total of about 7,000 Spring bean definitions...not including our core application code).
The problem is that the startup time is long (approximately 6.5 minutes of just plugin bean definition loading). We would prefer to spread this load time out over a much longer period while our app is actually processing other requests utilizing plugins that have already had their bean definitions registered. Most of the plugins are seldom used. Thus, we would really like to lazily register our bean definitions (this is different from lazy-init of singleton beans which we already do today). However, this seems costly with any existing Spring ApplicationContext that supports 'hot' refresh() calls (as the Spring documentation refers to it).
The Spring ApplicationContext classes that support 'hot' refresh start by destroying all of the singleton beans. Most of our plugins are singletons, so each call to refresh() would cause most of our plugins to be destroyed and then recreated...costly. If we don't call refresh, then our newly loaded plugin beans will not be post-processed (e.g., AOP, etc...).
We can guarantee that when we are forced to load another plugin, we will also load any of its dependencies that are not already loaded. So, we would never ben in a situation where a loaded bean definition is invalid.
It seems to me that this calls for a new type of Spring ApplicationContext that supports 'hot' refresh, but only for the purpose of adding new bean definitions. Preexisting bean definitions are not removed/reloaded, and not re-processed by BeanFactoryPostProcessors on subsequent refresh() calls, and pre-existing singletons are not destroyed!
Does this already exist?. Is there a better solution that I'm overlooking?
This sounds like you're looking for #Lazy.
4.4.4 Lazy-initialized beans
A lazy-initialized bean tells the IoC container to create a bean instance when it is first requested, rather than at startup.

Continue to load webapp even if one spring bean initialization fails

So if spring initialization fails in a webapp then the webapp itself does not come up. To prevent this, I can probably not re-throw any exception from my code for that specific bean initialization and the webapp will continue to load, right?
Is there any other way to tell to spring not to fail the webapp itself on particular bean initialization failure?
Continue to load webapp even if one spring bean initialization fails
AFAIK, you can't do this.
I do multiple DNS lookups on start up. I do not want the webapp to fail if one of them fails.
In that case, you need to modify your bean(s) to handle the case where the DNS lookup fails, leaving the bean instance in a state where it is essentially inactive but harmless, or where it can retry the DNS lookup later on.
In short, you have to cope with this yourself.
Have attribute lazy-init="true" in that bean and every dependant bean. Link for more details.
why would you do this? If your spring context is not correct, something is seriously wrong and there will be issues. The correct way to deal with this is to fix the application context.

Categories