一,自动配置原理
Springboot启动类注解时@Springbootapplication,该注解被四个元注解,三个自定义注解修饰,
自定义注解分别是@ComponentScan,这是启动类能够扫描本包及其子包所有类的原因,@SpringBootConfiguration,表明启动类是一个自动配置类,可以把springboot框架的起步依赖加载并纳入ioc容器来调用,最后是@EnableAutoConfiguration注解,也就是自动配置核心注解。
@EnableAutoConfiguration注解被@Import注解修饰,Import注解还配置了ImportSelector接口的实现类,重写了ImportSelector接口的selectImports()方法,方法底层调用了getAutoConfigurationEntry()方法,获取可自动配置的配置类信息集合,getAutoConfigurationEntry()方法通过调用getCandidateConfigurations(annotationMetadata, attributes)方法获取在配置文件中配置的所有自动配置类的集合,获取所有基于META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件、META-INF/spring.factories文件中配置类的集合。
自动配置源码小结
自动配置原理源码入口就是@SpringBootApplication注解,在这个注解中封装了3个注解,分别是:
-
@SpringBootConfiguration
-
声明当前类是一个配置类
-
-
@ComponentScan
-
进行组件扫描(SpringBoot中默认扫描的是启动类所在的当前包及其子包)
-
-
@EnableAutoConfiguration
封装了@Import注解(Import注解中指定了一个ImportSelector接口的实现类)- 在实现类重写的selectImports()方法,读取当前项目下所有依赖jar包中META-INF/spring.factories、META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports两个文件里面定义的配置类(配置类中定义了@Bean注解标识的方法)。
当SpringBoot程序启动时,就会加载配置文件当中所定义的配置类,并将这些配置类信息(类的全限定名)封装到String类型的数组中,最终通过@Import注解将这些配置类全部加载到Spring的IOC容器中,交给IOC容器管理。
二,Springboot自动配置常见方案
1,使用@Import导入普通类:
@Import(TokenParser.class) //导入的类会被Spring加载到IOC容器中 @SpringBootApplication
public class SpringbootWebConfig2Application {
public static void main(String[] args) { SpringApplication.run(SpringbootWebConfig2Application.class, args);
}
}
2). 使用@Import导入配置类:
-
配置类
@Configuration public class HeaderConfig { @Bean public HeaderParser headerParser(){ return new HeaderParser(); } @Bean public HeaderGenerator headerGenerator(){ return new HeaderGenerator(); } }
-
启动类
@Import(HeaderConfig.class) //导入配置类 @SpringBootApplication public class SpringbootWebConfig2Application { public static void main(String[] args) { SpringApplication.run(SpringbootWebConfig2Application.class, args); } }3). 使用@Import导入ImportSelector接口实现类:
3). 使用ImportSelector接口实现类
public class MyImportSelector implements ImportSelector { public String[] selectImports(AnnotationMetadata importingClassMetadata) { //返回值字符串数组(数组中封装了全限定名称的类) return new String[]{"com.example.HeaderConfig"}; } }
-
启动类
@Import(MyImportSelector.class) //导入ImportSelector接口实现类 @SpringBootApplication public class SpringbootWebConfig2Application { public static void main(String[] args) { SpringApplication.run(SpringbootWebConfig2Application.class, args); } }
- META.INF中的spring.factories:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.example.HeaderConfig
4). 使用第三方依赖提供的 @EnableXxxxx注解
-
第三方依赖中提供的注解
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Import(MyImportSelector.class)//指定要导入哪些bean对象或配置类 public @interface EnableHeaderConfig { }
-
在使用时只需在启动类上加上@EnableXxxxx注解即可
@EnableHeaderConfig //使用第三方依赖提供的Enable开头的注解 @SpringBootApplication public class SpringbootWebConfig2Application { public static void main(String[] args) { SpringApplication.run(SpringbootWebConfig2Application.class, args); } }
三,封装starter
在自定义一个起步依赖starter的时候,按照规范需要定义两个模块:
-
starter模块(进行依赖管理[把程序开发所需要的依赖都定义在starter起步依赖中])
-
autoconfigure模块(自动配置)
在自动配置模块中,引入封装工具类需要的依赖,然后分析业务逻辑写业务方法,写完工具类后,如果工具类中有需要配置属性,可以写一个自定义配置的属性类,用@ConfigurationProperties注解标明,然后写自动配置类,里面写好工具类的构造方法,加上@Bean注解,加上三个注解
@Configuration//表明是配置类,并在配置文件spring.factories中写上,让importselects方法扫描到。 @Component//加入ioc容器,自动配置属性类 @EnableConfigurationProperties(QiniuOssProperties.class)//指名自动配置属性类,给工具类赋值
然后打包引入starter模块,把starter模块加入项目依赖就好;