Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Injecting @Beans from within a very same @Configuration class idioms

In the past I have seen people using the following 2 idioms to inject dependencies from the same @Configuration:

@Configuration
public class MyConfiguration {

    @Bean
    public MyBeanDependencyA myBeanDependencyA(){
        return new MyBeanDependencyA();
    }

    @Bean . //IDIOM 1
    public MyBeanDependencyB1 myBeanDependencyB1(){
        return new MyBeanDependencyB1(myBeanDependencyA());
    }

    @Bean //IDIOM 2
    public MyBeanDependencyB2 myBeanDependencyB2(MyBeanDependencyA myBeanDependencyA){
        return new MyBeanDependencyB1(myBeanDependencyA);
    }
}

Is there any practical difference between them?

  • Does Spring process the whole instantiation method in each call for IDIOM 1? (relevant if method has any side-effect, might be not idempotent)?
  • Does otherwise Spring inject the global managed instance when injecting for IDIOM 1? (relevant If some external process changes the state of the original singleton bean)

Is Spring container that smart?

like image 725
Whimusical Avatar asked Nov 26 '19 21:11

Whimusical


People also ask

What is a bean in Spring?

In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. 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.

How does dependency injection work in Spring?

Dependency Injection is a fundamental aspect of the Spring framework, through which the Spring container “injects” objects into other objects or “dependencies”. Simply put, this allows for loose coupling of components and moves the responsibility of managing components onto the container.

How do Spring containers work internally?

The Spring container is at the core of the Spring Framework. The container will create the objects, wire them together, configure them, and manage their complete life cycle from creation till destruction. The Spring container uses DI to manage the components that make up an application.

How do you call a bean in a Spring boot?

To declare a bean, simply annotate a method with the @Bean annotation. When JavaConfig encounters such a method, it will execute that method and register the return value as a bean within a BeanFactory .


2 Answers

Does Spring process the whole instantiation method in each call for IDIOM 1? (relevant if method has any side-effect, might be not idempotent)?

By default @Configuration classes are proxied at runtime so the MyBeanDependencyA will be created once and myBeanDependencyA() will be called only once by Spring and next calls will be proxied to return the same instance (as far as example that you shared is concerned). There will be only one instance of this bean in the context as it's scope is Singleton.


Does otherwise Spring inject the global managed instance when injecting for IDIOM 1? (relevant If some external process changes the state of the original singleton bean)

The IOC container will return same instance of Singleton bean when it is queried to do so. Since it is a Singleton all changes to this bean (if it is mutable) will be visible to components that have reference to it.


As a side note you can disable autoproxing of configuration class since Spring 5.2 by using :

@Configuration(proxyBeanMethods = false)

which will prevent proxying calls of methods annotated with @Bean invoked from other @Bean methods.

like image 144
Michał Krzywański Avatar answered Nov 15 '22 08:11

Michał Krzywański


Does Spring process the whole instantiation method in each call for IDIOM 1?

No, This is called inter-bean dependencies, a method that annotated with @Bean annotation in @Configuration class will create a bean in spring IOC container

The @Bean annotation is used to indicate that a method instantiates, configures and initializes a new object to be managed by the Spring IoC container. For those familiar with Spring's XML configuration the @Bean annotation plays the same role as the element. You can use @Bean annotated methods with any Spring @Component, however, they are most often used with @Configuration beans.


Does otherwise Spring inject the global managed instance when injecting for IDIOM 1?

Yes, spring injects the same bean if it is required at multiple places Basic concepts: @Bean and @Configuration This inter-bean dependencies will only work in combination of @Bean and @Configuration which also prevents calling same bean method multiple times.

Only using @Bean methods within @Configuration classes is a recommended approach of ensuring that 'full' mode is always used. This will prevent the same @Bean method from accidentally being invoked multiple times and helps to reduce subtle bugs that can be hard to track down when operating in 'lite' mode.

like image 36
Deadpool Avatar answered Nov 15 '22 07:11

Deadpool