先看下@SpringBootApplication这个注解,这是一个组合注解,部分源码以下:git
@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这个注解,这个就是自动配置的核心所在,接下来看下这个注解的源码:github
@SuppressWarnings("deprecation") @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(EnableAutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration { //省略若干行代码... }
能够发现此处导入了EnableAutoConfigurationImportSelector.class这个类,继续观察EnableAutoConfigurationImportSelector这个类的源码web
public class EnableAutoConfigurationImportSelector extends AutoConfigurationImportSelector { //省略若干行代码 }
发现继承于AutoConfigurationImportSelector这个类,发现有以下代码spring
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; }
这里扫描了具备META-INF/spring.factories文件的jar包。点开具备*autoconfigure的包,打开META-INF/spring.factories文件,发现有相似org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration
,打开任意一个AutoConfiguration,能够发现有以下注解:安全
@Configuration @EnableConfigurationProperties(UeditorProperties.class) @ConditionalOnClass(ActionEnter.class) @ConditionalOnProperty(prefix="ueditor",value="enabled",matchIfMissing=true)
这里即是spring-boot自动配置的秘密所在了,接下来本身建一个项目,让其也拥有自动配置的功能:当类存在时,自动配置这个类的Bean,并可将Bean的属性在appliction.properties中配置。springboot
<dependencies> <!--自动配置--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> <version>${spring-boot}</version> </dependency> <!--属性的自动注入--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> <version>${spring-boot}</version> </dependency> </dependencies>
@ConfigurationProperties(prefix = "hello") public class HelloServiceProperties { private static final String MSG = "world"; private String msg = MSG; public static String getMSG() { return MSG; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }
public class HelloService { private String msg; public String sayHello(){ return "hello"+msg; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }
@Configuration @EnableConfigurationProperties(HelloServiceProperties.class) @ConditionalOnClass(HelloService.class) public class HelloServiceAutoConfigure { @Autowired private HelloServiceProperties helloServiceProperties; @Bean @ConditionalOnMissingBean(HelloService.class) public HelloService helloService() { HelloService helloService = new HelloService(); helloService.setMsg(helloServiceProperties.getMsg()); return helloService; } }
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.xiake.springboot.start.hello.HelloServiceAutoConfigure
这里,一个拥有自动配置的项目完成。在其余项目中引用maven坐标,并在application.properties中自定义hello.msg="xxx".使用代码以下:app
@Autowired HelloService helloService; @ResponseBody @RequestMapping("/sayHello") public ResponseData sayHello(HttpServletRequest request){ return ResponseData.success(helloService.sayHello()); //输出hello.msg中的内容:xxx }
项目源码地址maven