spring boot 自动配置
1.Spring boot 自动配置
spring boot 通过@springbootapplication来启动项目,使用@springbootapplication标记过的类证明是这个类的主程序,程序通过运行这个类的main方法来启动这个程序
@SpringBootApplication
public class SpringBootTestApp {
public static void main(String[] args){
//启动注册中心
SpringApplication.run(SpringBootTestApp.class,args);
}
@SpringBootApplication 该类中主要包含了@SpringBootConfiguration@EnableAutoConfiguration等五个注解
/**
该注解标记了@Springbootapplication这个注解可以标记在什么位置上,@Target可以应用于TYPE、FIELD、METHOD、PARAMETER、CONSTRUCTOR、LOCAL_VARIABLE、ANNOTATION_TYPE、PACKAGE、TYPE_PARAMETER 修饰类型用于类的、TYPE_USE,TYPE修饰类、接口、枚举,FIELD 属性,METHOD 方法,PARAMETER 方法上的参数,CONSTRUCTOR用于构造方法,LOCAL_VARIABLE 局部变量,ANNOTATION_TYPE 注解,PACKAGE 修饰包 TYPE_PARAMETER 修饰类型用于泛型,TYPE_USE 修饰类型只要是类型名称都可以使用该注解*/
@Target({ElementType.TYPE})
/**
Retention该注解标明了此注解的生命周期,RetentionPolicy.SOURC:只标识在源码阶段,RetentionPolicy.CLASS:注解保留在class文件中,在加载到虚拟机是被丢弃
RetentionPolicy.RUNTIME:保留在程序运行期间,此时可以通过反射获取定义在某个元素上的注解
*/
@Retention(RetentionPolicy.RUNTIME)
/**
@Documented 注解表明这个注解应该被 javadoc工具记录,默认javadoooc不记录注解
*/
@Documented
/**说注解和普通类的区别是如果一个子类想获取到父类上的注解信息,
那么必须在父类上使用的注解上面 加上@Inherit关键字 */
@Inherited
/**
@SpringBootConfiguration 使用该注解标识的类为springboot项目的配置类
*/
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
1.@SpringBootConfiguration
@SpringBootConfiguration 使用该注解标识的类为springboot项目的配置类
@SpringBootConfiguration 使用了@configuration注解标识这个类为配置类
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
@configuration使用了@component标识了,证明了这个类会被spring boot 管理(
@Service用于标注业务层组件
@Controller用于标注控制层组件(如struts中的action)
@Repository用于标注数据访问组件,即DAO组件,
@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注)
2.@EnableAutoConfiguration
@EnableAutoConfiguration 字面理解为开启自动注解,该注解又依赖于@**AutoConfigurationPackage**
@Import(**AutoConfigurationPackage**.class)。
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
/**
* Exclude specific auto-configuration classes such that they will never be applied.
* @return the classes to exclude
*/
Class<?>[] exclude() default {};
/**
* Exclude specific auto-configuration class names such that they will never be
* applied.
* @return the class names to exclude
* @since 1.3.0
*/
String[] excludeName() default {};
}
1.AutoConfigurationPackage
@AutoConfigurationPackage依赖于Import,import 用于将AutoConfigurationPackages声明注册到Spring 容器中
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
}
AutoConfigurationPackages.package,通过这个方法获取@springbootapplication标注类的所在包下的所有组件扫描
/**
* {@link ImportBeanDefinitionRegistrar} to store the base package from the importing
* configuration.
*/
@Order(Ordered.HIGHEST_PRECEDENCE)
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata,
BeanDefinitionRegistry registry) {
register(registry, new PackageImport(metadata).getPackageName());
}
@Override
public Set<Object> determineImports(AnnotationMetadata metadata) {
return Collections.<Object>singleton(new PackageImport(metadata));
}
}
2.EnableAutoConfigurationImportSelector
@Import(EnableAutoConfigurationImportSelector.class)将EnableAutoConfigurationImportSelector注册到spring 中,EnableAutoConfigurationImportSelector继承了AutoConfigurationImportSelector
public class EnableAutoConfigurationImportSelector extends AutoConfigurationImportSelector {
@Override
protected boolean isEnabled(AnnotationMetadata metadata) {
if (getClass().equals(EnableAutoConfigurationImportSelector.class)) {
return getEnvironment().getProperty( EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, Boolean.class,
true);
}
return true;
}
}
AutoConfigurationImportSelector读取了spring.factories这个配置文件并将里边的配置自动配置类加载到spring容器中并对spring boot 进行
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
try {
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
AnnotationAttributes attributes = getAttributes(annotationMetadata);
List<String> configurations = getCandidateConfigurations(annotationMetadata,
attributes);
configurations = removeDuplicates(configurations);
configurations = sort(configurations, autoConfigurationMetadata);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
return configurations.toArray(new String[configurations.size()]);
}
catch (IOException ex) {
throw new IllegalStateException(ex);
}
}