我正在为Spring Boot创建自定义AutoConfiguration . 我尝试创建的一个功能是动态创建一个或多个Bean,并在运行时将它们添加到ApplicationContext .

我遇到的问题是自动装配 . 我的@SpringBootApplication类自动装配那些bean,因为它们还不存在,所以autowire失败了 .

我的第一个解决方案是将@Lazy放在autowire上,这解决了我的问题 .

但是,我遇到了一些有趣的事情 . 我在AutoConfiguration代码中添加了两个我正在寻找的bean,当然,它有效 . 不小心,我只删除了其中一个bean并重新运行了我的代码 . 有效 .

@SpringBootApplication
public class SpringBootDemoApplication {
    @Autowired
    @Qualifier("some_name")
    private MyClass myClass;

    @Autowired
    @Qualifier("another_name")
    private MyClass anotherClass;

    ...
}

@Configuration
public class MyAutoConfigurationClass {
    @Bean(name="some_class")
    public MyClass myClass () {
        return null;
    }
}

所以缺点就是这个 . 如果我在我的autoconfiguration类中只定义了一个bean,这似乎满足Autowired并且它不会爆炸,当我动态添加我的其他bean时,会找到这两个bean .

规定是首先使用的Autowired bean必须是我的autoconfiguration类中定义的bean .

我正在运行以下内容:

  • Spring Boot Starter 1.5.7-RELEASE

  • 各种Spring Framework 4.3.11-RELEASE

这是一个错误吗?或者这是Autowired应该工作的方式吗?


@SpringBootApplication
public class SpringBootDemoApplication {

    @Autowired
    @Qualifier("myclass")
    private MyClass myClass;

    @Autowired
    @Qualifier("anotherMyClass")
    private MyClass anotherMyClass;
    ...
}

@Configuration
public class MyAutoConfiguration {

    private ConfigurableApplicationContext applicationContext;

    private final BeanFactory beanFactory;

    @Autowired
    private MyClassFactory myClassFactory;

    public MyAutoConfiguration(ApplicationContext applicationContext, BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
        this.applicationContext = (ConfigurableApplicationContext) applicationContext;
    }

    @PostConstruct
    public void init() throws IOException, SQLException {
        this.myClassFactory.create(this.applicationContext);
    }

    //  without this @Bean definition SpringBoot will recieve the following error and stop
    //  AnnotationConfigEmbeddedWebApplicationContext - Exception encountered during context initialization
    @Bean(name="myClass")
    public DataSource anyNameWillDoItDoesntMatter() {
        return null;
    };
}

@Component
class MyClassFactory {
    public void create(ConfigurableApplicationContext applicationContext) {
        applicationContext.getBeanFactory().registerSingleton(name, value);
    }
}

那么@Autowired的预期行为是什么?