spring-boot自动配置

先看下@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)
  • @Configuration
  • EnableConfigurationProperties 属性注入类
  • ConditionalOnClass 条件注解,当容器有指定的Bean的条件下。
  • ConditionalOnProperty 条件注解,指定属性是否有指定的值,这个注解测试了下,没有达到预期效果,不知道怎么回事。

这里即是spring-boot自动配置的秘密所在了,接下来本身建一个项目,让其也拥有自动配置的功能:当类存在时,自动配置这个类的Bean,并可将Bean的属性在appliction.properties中配置。springboot

  • pom中引入相关组件
<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;
    }
}
  • 根据HelloService这个类是否存在,来建立这个类的Bean
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;
    }
}
  • 注册自动配置类,在src/main/resources目录下,新建META-INF目录并在其中新建spring.factories文件,输入以下代码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

相关文章
相关标签/搜索