平常我們如何將 Bean 注入到容器當中
@Configuration
@EnableConfigurationProperties(HelloProperties.class)
public class HelloServiceAutoConfiguration {
@Autowired
HelloProperties helloProperties;
@Bean
public HelloService helloService() {
HelloService service = new HelloService();
service.setHelloProperties( helloProperties );
return service;
}
}
一般就建立配置文件使用 @Configuration, 里面通過 @Bean 進行加載 bean
或者使用 @Compont 注解在類上進行類的注入
注意:
在我們主程序入口的時候:
@SpringBootApplication 這個注解里面的東西
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
里面注解 @EnableAutoConfiguration
@ComponentScan 注解指掃描 @SpringBootApplication 注解的入口程序類所在的 basepackage 下的
所有帶有 @Component 注解的 bean,從而注入到容器當中。
但是
如果是加入 maven 坐標依賴的 jar 包,就是項目根目錄以外的 Bean 是怎么添加的??
這個時候注解 @EnableAutoConfiguration 的作用就來了
導入了 AutoConfigurationImportSelector 這個類:
這個類里面有一個方法
/**
* Return the auto-configuration class names that should be considered. By default
* this method will load candidates using {@link SpringFactoriesLoader} with
* {@link #getSpringFactoriesLoaderFactoryClass()}.
* @param metadata the source metadata
* @param attributes the {@link #getAttributes(AnnotationMetadata) annotation
* attributes}
* @return a list of candidate configurations
*/
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}
@EnableAutoConfiguration
注解來注冊項目包外的 bean。而 spring.factories 文件,則是用來記錄項目包外需要注冊的 bean 類名
為什么需要spring.factories文件,
因為我們整個項目里面的入口文件只會掃描整個項目里面下的@Compont @Configuration等注解
但是如果我們是引用了其他jar包,而其他jar包只有@Bean或者@Compont等注解,是不會掃描到的。
除非你引入的jar包沒有Bean加載到容器當中
所以我們是通過寫/META-INF/spring.factories文件去進行加載的。