SpringBoot如何加载代码根目录之外的Bean
这片文章中会找到你想要的答案。
*看一个SpringBoot入口类
package com.example.multithread;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MultithreadApplication {
public static void main(String[] args) {
SpringApplication.run(MultithreadApplication.class, args);
}
}
*耀眼的@SpringBootApplication注解
*它继承了哪些注解
(加在它之上的注解)
1-首先是四个元注解
@Target(ElementType.TYPE)
标志该注解可以作用于interface、class、enum。
@Retention(RetentionPolicy.RUNTIME)
注解的保留策略;
这里的策略是:
当前注解会出现在.class字节码文件中,
并且在运行的时候可以通过反射被获得。
@Documented
标志该注解可以被javadoc工具所引用。
@Inherited
标志该注解可以被继承。
2-@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan
@SpringBootApplication相当于是这三个注解的组合,
我们主要说一下这三个。
*@SpringBootConfiguration
可以看到它继承了@Configuration;
Spring3.0开始增加了@Configuration、@Bean注解,
支持通过Java类(JavaConfig)的形式进行更直观的配置。
例如:
@Bean
public HttpMessageConverters fastjsonHttpMessageConverter(){
//定义消息转换对象
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
HttpMessageConverter<?> converter = fastConverter;
return new HttpMessageConverters(converter);
}
*@ComponentScan
@ComponentScan与@Component这一类的注解配合使用,
相当于以前xml配置中开启自动扫描的context:component-scan标签,
可以配置Spring的扫描范围、Bean的ID命名策略等属性;
默认扫描范围为当前目录下的所有class,
这也是SpringBoot入口类要放在代码根目录的原因。
*@EnableAutoConfiguration
需要注意一下这个@Import(AutoConfigurationImportSelector.class)
@ComponentScan会扫描并装配代码根目录下的,
所有的带@Component注解的class;
但是SpringBoot如何加载代码根目录之外的Bean,
比方说classpath下maven依赖中的;
这个时候就需要了解一下META-INF/spring.factories文件的作用了。
1-META-INF/spring.factories
META-INF/spring.factories存在于某些依赖的jar包中
它里面有一个属性:EnableAutoConfiguration。
2-EnableAutoConfiguration
它用来记录jar包中需要注册到容器中的Bean的qualified name,
这样可以通过反射获取到对应的class,
然后前边@Import中的AutoConfigurationImportSelector.class就该工作了。
3-AutoConfigurationImportSelector
它里边有一个方法:
getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes),
作用是加载这些定义在spring.factories中的Bean。
不当之处,还请指正!