spring-boot提倡通过annotation来进行bean的配置,现在spring-boot里面常用的两种创建bean的方式有auto-configuration和configuration两种方式。
先说说configuration方式,就是使用@configuration
注解和@bean
注解来初始化想要的bean对象
@Configuration
@Slf4j
public class SecondBeanConfiguration {
@Bean
@ConditionalOnMissingBean
public SecondBean secondBean() {
log.info("log second bean");
return new SecondBean("secondBean", 2);
}
}
然后在启动的时候@ComponentScan
注解会扫描包(路径可以指定,默认的情况下就是这个目录所在的包开始扫描),这个注解扫到@configuration
注解以后,就会初始化这个类下面所有加了@bean
的方法,并初始化这个bean
再来说说auto-configuration,spring-boot有一个@EnableAutoConfiguration
注解,他通过读取spring.factories
文件里面的EnableAutoConfiguration下面指定的类,来初始化指定类下面的所有加了@bean
的方法,并初始化这个bean
spring.factories文件:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.dragon.study.spring.boot.configuration.auto.config.AutoFirstBeanConfiguration,\
com.dragon.study.spring.boot.configuration.auto.config.AutoSecondBeanConfiguration
具体的代码
@Slf4j
@Configuration
public class AutoFirstBeanConfiguration {
@Bean
@ConditionalOnMissingBean
public AutoFirstBean autoFirstBean() {
log.info("log auto first bean");
return new AutoFirstBean("autoFirstBean", 1);
}
}
那么这两种方式有什么不同呢?
- 就是初始化的时机configuration初始化的方式总是在auto-configuration初始化方式之前
- configuration初始化的顺序和扫描的过程相关,并不能进行有效的进行指定,不方便确定文件加载的顺序
- auto-configuration可以通过
@AutoConfigureAfter
@AutoConfigureBefore
和@AutoConfigureOrder
来指定类的加载顺序 - configuration初始化会先初始化所有被扫到加了
@Configuration
文件的@PostConstruct
注解然后再初始化这些文件里面的@Bean
注解,但是auto-configuration是根据文件来进行初始化的,所以会初始化完一个文件的@PostConstruct
注解然后再初始化这个文件的@Bean
注解,然后再接着处理另外的文件。
所以需要提供bean给其他jar包进行使用的时候,最好使用 auto-configuration 方式(spring-boot-starters
里面的都是通过这种方式来进行提供的,他的所有初始化的过程全部在spring-boot-autoconfigure
项目中),因为能更好的控制类文件的加载顺序。有助于维护更佳复杂的项目。
另外需要注意一点的就是,如果auto-configuration提供的类名称在扫描的路径之中,spring-boot会把这些类作为configuration先进行初始化了,然后@AutoConfigureAfter
@AutoConfigureBefore
和 @AutoConfigureOrder
这类指定顺序的注解都会失效。