Spring Boot自定义自动配置和自动装配

时间:2017-09-22 20:42:52

标签: spring spring-boot autowired spring-bean

我正在为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必须是我的自动配置类中定义的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的预期行为是什么?

0 个答案:

没有答案