Search code examples
javaspringspring-annotations

Why does in my case context creates the bean?


Could you tell me why does in my case context creates the "simple" bean if it has circular dependencies? To my mind, an exception that says about circular dependencies must be thrown! Configuration class:

package config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = "service")
public class AppConfig {
}

Simple class:

package service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Simple {

    @Autowired
    private Simple simple;


    public Simple getSimple() {
        return simple;
    }
}

And the launcher:

import config.AppConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import service.Simple;


public class Launcher {

    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
        Simple simple1 = ctx.getBean("simple", Simple.class);
        System.out.println(simple1.getSimple());
    }

}

The output of the app is "service.Simple@6b53e23f". If I add the constructor

@Autowired
public Simple(Simple simple) {
    this.simple = simple;
}

then an exception "Error creating bean with name 'simple': Requested bean is currently in creation: Is there an unresolvable circular reference?" occurs.

So why is the bean created when I put @Autowired n the field?


Solution

  • Because setting of the simple field is only done after creating the Simple instance and at that point you have a valid Simple instance to assign to the field. That is field injection. You do not need an instances of the the autowired fields when creating the instance of your Simple class.

    Using constructor injection on the other hand you need valid instances for all the constructor parameters. So you need a Simple instance to create an instance of Simple which of course does not work.