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

相關文章
相關標籤/搜索