Search code examples
springautowiredspring-config

Spring - @Autowired bean from @Configuration is null


I define a bean in a configuration class. I would like to autowire this bean in a component. However, the property stays null. E.g.:

Appconfiguration.java

@Configuration
public class AppConfiguration {

    @Bean
    public SomeType someObject() {
        return new SomeType();
    }
}

AppComponent.java

@Component
public class AppComponent {

    @Autowired
    private SomeType someObject;  // TODO why null?

    public AppComponent() {  // note: passing a SomeType constructor argument works
        System.out.println(someObject);
    }
}

How can I autowire a bean defined in a configuration class?


Solution

  • Are you missing a fundamental detail that properties are injected after a bean is created? Have you tried access your property after a bean is fully initialized?

    Update: I've reworked your example a little to demonstrate you the difference:

    @Test
    public void initializationTest() {
        try (AnnotationConfigApplicationContext context =
                     new AnnotationConfigApplicationContext()) {
            context.register(AppConfiguration.class, AppComponent.class);
            context.refresh();
        }
    }
    
    @Configuration
    public class AppConfiguration {
    
        @Bean
        public SomeType someObject() {
            return new SomeType();
        }
    }
    
    
    @Component
    public class AppComponent {
    
        @Autowired
        private SomeType someObject;
    
        public AppComponent() {
            // Here properties are not yet injected by Spring IoC container
            System.out.println(someObject); // Obviously prints null
        }
    
        /**
         * Method is invoked after a bean is initialized and all its properties are being set.
         */
        @PostConstruct
        private void init() {
            System.out.println(someObject); // Prints SomeType@6b419da
        }
    }
    
    public class SomeType {
    }
    

    So basically bean lifecycle consists of the following steps:

    1. Bean instance is created
    2. Bean properties are set
    3. In case bean implements Aware interfaces - those implemented methods are invoked
    4. BeanPostProcessor#postProcessBeforeInitialization methods of custom bean post-processors are invoked
    5. Initialization callbacks are invoked in the following order:
    5.1. @PostConstruct method is invoked
    5.2. InitializingBean#afterPropertiesSet() method is invoked
    5.3. @Bean#initMethod() method is invoked
    Bean is fully initialized now.
    6. BeanPostProcessor#postProcessAfterInitialization methods of custom post-processors are invoked are invoked.
    7. Destruction callbacks are invoked in the following order:
    7.1. @PreDestroy method is invoked
    7.2. DisposableBean#destroy() method is invoked
    7.3. @Bean#destroyMethod method is invoked