Spring Boot之实现自动配置
GITHUB地址:https://github.com/zhangboqing/springboot-learning
一、Spring Boot自动配置原理
自动配置功能是由@SpringBootApplication中的@EnableAutoConfiguration注解提供的。
1 @Target(ElementType.TYPE) 2 @Retention(RetentionPolicy.RUNTIME) 3 @Documented 4 @Inherited 5 @AutoConfigurationPackage 6 @Import(AutoConfigurationImportSelector.class) 7 public @interface EnableAutoConfiguration { 8 9 String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; 10 11 /** 12 * Exclude specific auto-configuration classes such that they will never be applied. 13 * @return the classes to exclude 14 */ 15 Class<?>[] exclude() default {}; 16 17 /** 18 * Exclude specific auto-configuration class names such that they will never be 19 * applied. 20 * @return the class names to exclude 21 * @since 1.3.0 22 */ 23 String[] excludeName() default {}; 24 25 }
这里的关键功能是@Import(AutoConfigurationImportSelector.class),它导入了AutoConfigurationImportSelector类,该类使用了SpringFactoriesLoader.loadFactoryNames方法来扫描具有META-INF/spring.factories文件的jar包。
1 protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, 2 AnnotationAttributes attributes) { 3 List<String> configurations = SpringFactoriesLoader.loadFactoryNames( 4 getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()); 5 Assert.notEmpty(configurations, 6 "No auto configuration classes found in META-INF/spring.factories. If you " 7 + "are using a custom packaging, make sure that file is correct."); 8 return configurations; 9 }
并且在META-INF/spring.factories中定义了需要自动配置的具体类是什么
1 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 com.zbq2.autoconfig.HelloServiceAutoConfiguration
二、如何实现自动配置功能
1.新建stater maven项目
增加Spring Boot自身的自动配置maven依赖
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-autoconfigure -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
2.属性配置
HelloServiceProperties
自定义一个获取属性的类,可以获取在application.properties中设置的自定义属性
1 /** 2 * @author zhangboqing 3 * @date 2018/6/29 4 */ 5 @Data 6 @ConfigurationProperties(prefix = "hello") 7 public class HelloServiceProperties { 8 9 private static final String MSG = "world"; 10 11 private String msg = MSG; 12 }
3.判断依据类
HelloService
定义一个类,通过判断该类是否存在,来创建该类的Bean,该类可以是第三方库的类如DataSource
1 /** 2 * @author zhangboqing 3 * @date 2018/6/29 4 */ 5 @Data 6 public class HelloService { 7 8 private String msg; 9 10 public String sayHello() { 11 return new StringBuilder("Hello").append(msg).toString(); 12 } 13 }
4.自动配置类
HelloServiceAutoConfiguration
根据HelloServiceProperties提供的参数,并通过@ConditionalOnClass判断HelloService这个类在类路径中是否存在,且当容器中没有这个Bean的情况下自动配置这个Bean
1 /** 2 * @author zhangboqing 3 * @date 2018/6/29 4 */ 5 @Configuration 6 @EnableConfigurationProperties(HelloServiceProperties.class) 7 @ConditionalOnClass(HelloService.class) 8 @ConditionalOnProperty(prefix = "hello",matchIfMissing = true) 9 public class HelloServiceAutoConfiguration { 10 11 @Autowired 12 private HelloServiceProperties helloServiceProperties; 13 14 @Bean 15 @ConditionalOnMissingBean(HelloService.class) 16 public HelloService helloService() { 17 HelloService helloService = new HelloService(); 18 helloService.setMsg(helloServiceProperties.getMsg()); 19 return helloService; 20 } 21 22 }
5.注册配置
若想自动配置生效,需要注册自动配置类。在src/main/resources下新建META-INF/spring.factories
如下:
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration
若有多个自动配置,则用','隔开,此处'\'是为了换行后仍能读到属性
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.zbq2.autoconfig.HelloServiceAutoConfiguration
6.使用starter 作为其他项目的依赖
引入maven 坐标依赖