Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to prevent bean overriding with Spring Boot?

With Spring's AbstractRefreshableApplicationContext, I am able to force Spring to fail if there is a conflict in Bean IDs or circular references by setting a couple of flags and refreshing the context like so:

AbstractRefreshableApplicationContext refreshableContext;
...
refreshableContext.setAllowBeanDefinitionOverriding(false);
refreshableContext.setAllowCircularReferences(false);
refreshableContext.refresh();

However, Spring Boot returns a ConfigurableApplicationContext which is not an instance of AbstractRefreshableApplicationContext and does not appear to have any means to prevent bean definition overriding or circular references.

Does anyone know of a way and have an example of how to prevent these types of conflicts?

For context, this is for a large project that has a mix of annotated and xml defined beans. The version of Spring Boot used is 1.3.1.RELEASE. There have been some cases where folks added duplicate bean definitions in the xml, but the application started up fine and wasn't immediately apparent the original bean was overridden until run-time issues started occurring.

The goal here is to prevent the application from event starting up if such a conflict occurs. From various forums I know Spring IDE can detect these, but the desire is to enforce this in the CI build which is a stronger safety net.

After some searching, I can't find any support for this in the context that Sprint Boot returns. If this can't be done through the context, is there a different solution available?

Thanks in advance.

like image 635
Hazok Avatar asked Aug 05 '16 17:08

Hazok


People also ask

Can @bean method be private?

Any @Bean annotated method, which is not public (i.e. with protected, private and default visibility), will create a 'hidden' bean.

Can we have 2 beans with same ID in Spring?

Here, @Bean instantiates two beans with ids the same as the method names and registers them within the BeanFactory (Spring container) interface. Next, we can initialize the Spring container and request any of the beans from the Spring container. This strategy also makes it simple to achieve dependency injection.

How are beans managed in Spring boot?

A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your application. Beans, and the dependencies among them, are reflected in the configuration metadata used by a container.

Can we override bean in Spring?

Bean Overriding Spring beans are identified by their names within an ApplicationContext. Therefore, bean overriding is a default behavior that happens when we define a bean within an ApplicationContext that has the same name as another bean. It works by simply replacing the former bean in case of a name conflict.


1 Answers

You may use an initializer when building your Spring Boot app:

@SpringBootApplication
public class SpringBootApp {

    public static void main(String... args) {
        new SpringApplicationBuilder(SpringBootApp.class)
            .initializers(new ApplicationContextInitializer<GenericApplicationContext>() {
                @Override
                public void initialize(GenericApplicationContext applicationContext) {
                    applicationContext.setAllowBeanDefinitionOverriding(false);
                }
            })
        .run(args);

    }
}

Or with java 8:

new SpringApplicationBuilder(SpringBootApp.class)
    .initializers((GenericApplicationContext c) -> c.setAllowBeanDefinitionOverriding(false) )
    .run(args);
like image 148
alexbt Avatar answered Oct 02 '22 09:10

alexbt