一:原理

1.

  首先Spring Boot项目中都会如下启动类:

@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

  其中,@SpringBootApplication中有三个重要的注解合一。

@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的作用。

 @Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(EnableConfigurationPropertiesImportSelector.class)
public @interface EnableConfigurationProperties {

2.作用

  借助AutoConfigurationImportSelector@EnableAutoConfiguration可以帮助SpringBoot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot创建并使用的IoC容器。

  借助于Spring框架原有的一个工具类:SpringFactoriesLoader的支持,@EnableAutoConfiguration可以智能的自动配置功效才得以大功告成!

3.进一步说明如何加载

  在AutoConfigurationImportSelector类中可以看到通过 SpringFactoriesLoader.loadFactoryNames()把 spring-boot-autoconfigure.jar/META-INF/spring.factories中每一个xxxAutoConfiguration文件都加载到容器中。

  spring.factories文件里每一个xxxAutoConfiguration文件一般都会有下面的条件注解:

  @ConditionalOnClass : classpath中存在该类时起效
  @ConditionalOnMissingClass : classpath中不存在该类时起效
  @ConditionalOnBean : DI容器中存在该类型Bean时起效
  @ConditionalOnMissingBean : DI容器中不存在该类型Bean时起效
  @ConditionalOnSingleCandidate : DI容器中该类型Bean只有一个或@Primary的只有一个时起效
  @ConditionalOnExpression : SpEL表达式结果为true时
  @ConditionalOnProperty : 参数设置或者值一致时起效
  @ConditionalOnResource : 指定的文件存在时起效
  @ConditionalOnJndi : 指定的JNDI存在时起效
  @ConditionalOnJava : 指定的Java版本存在时起效
  @ConditionalOnWebApplication : Web应用环境下起效
  @ConditionalOnNotWebApplication : 非Web应用环境下起效

二:示例

1.结构

  

2.说明

  在加载的时候,会通过一些注解进行匹配,然后都通过了,@EnableConfiguration才可以加载。

  同时,可以不写@SpringBootApplication注解了。

3.说明项目

  一共两个。

  第一个是加载合适的bean

  第二个是使用。

三:项目一

1.pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.jun</groupId>
<artifactId>enableautoconfiguration</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>enableautoconfiguration</name>
<description>Demo project for Spring Boot</description> <properties>
<java.version>1.8</java.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>2.0.4.RELEASE</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies> </project>

2.hello

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.jun</groupId>
<artifactId>enableautoconfiguration</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>enableautoconfiguration</name>
<description>Demo project for Spring Boot</description> <properties>
<java.version>1.8</java.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>2.0.4.RELEASE</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies> </project>

3.helloproperties

package com.jun.enableautoconfiguration;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "hello") //获取属性值
public class HelloProperties {
private static final String MSG = "world"; private String msg = MSG ; public String getMsg() {
return msg;
} public void setMsg(String msg) {
this.msg = msg;
}
}

4.helloautoconfiguration

 package com.jun.enableautoconfiguration;

 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; @Configuration //为带有@ConfigurationProperties注解的Bean提供有效的支持。
// 这个注解可以提供一种方便的方式来将带有@ConfigurationProperties注解的类注入为Spring容器的Bean。
@EnableConfigurationProperties(HelloProperties.class) //开启属性注入,通过@autowired注入
@ConditionalOnClass(Hello.class) //判断这个类是否在classpath中存在,如果存在,才会实例化一个Bean
@ConditionalOnProperty(prefix="hello", value="enabled", matchIfMissing = true)
public class HelloAutoConfiguration { @Autowired
private HelloProperties helloProperties; @Bean
@ConditionalOnMissingBean(Hello.class)//容器中如果没有Hello这个类,那么自动配置这个Hello
public Hello hello() {
Hello hello = new Hello();
hello.setMsg(helloProperties.getMsg());
return hello;
} }

5.spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.jun.enableautoconfiguration.HelloAutoConfiguration

四:使用项目

1.application.properties

#可以不配置
hello.enabled=true hello.msg=uuibiu #以debug模式运行
debug=true

2.WenApplication

 package com.jun.web;

 import com.jun.enableautoconfiguration.Hello;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; @SpringBootApplication
@EnableAutoConfiguration
@RestController
public class WebApplication {
private static final Logger logger = LoggerFactory.getLogger(WebApplication.class); @Autowired
private Hello hello; @RequestMapping("/")
public String index() {
return hello.sayHello();
} public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(WebApplication.class, args);
ConfigurableEnvironment environment = context.getEnvironment();
logger.info("hello.msg:{}",environment.getProperty("hello.msg")); } }

007 SpringBoot的@EnableAutoConfiguration注解的更多相关文章

  1. SpringBoot之@EnableAutoConfiguration注解

    源地址:https://blog.csdn.net/zxc123e/article/details/80222967 虽然定义使用了多个Annotation进行了原信息标注,但实际上重要的只有三个An ...

  2. SpringBoot中@EnableAutoConfiguration注解用法收集

    参考: http://blog.csdn.net/xiaoyu411502/article/details/52770723 https://docs.spring.io/spring-boot/do ...

  3. SpringBoot自动配置注解原理解析

    1. SpringBoot启动主程序类: @SpringBootApplication public class DemoApplication { public static void main(S ...

  4. @EnableAutoConfiguration注解原理

    前言 Spring Boot中引入了自动配置,让开发者利用起来更加的简便.快捷.比如内嵌的tomcat端口默认配置是8080,这些都属于Spring Boot自动配置的范畴,当然其自动配置相当多. s ...

  5. SpringBoot自动化配置之三:深入SpringBoot:自定义EnableAutoConfiguration

    前言 上面几篇文章介绍了SpringFramework的一些原理,这里开始介绍一下SpringBoot,并通过自定义一些功能来介绍SpringBoot的原理.SpringBoot在SpringFram ...

  6. 【Spring Boot源码分析】@EnableAutoConfiguration注解(一)@AutoConfigurationImportSelector注解的处理

    Java及Spring Boot新手,首次尝试源码分析,欢迎指正! 一.概述 @EnableAutoConfiguration注解是Spring Boot中配置自动装载的总开关.本文将从@Enable ...

  7. SpringBoot相关的注解

    一.注解(annotations)列表 @SpringBootApplication:包含了@ComponentScan.@Configuration和@EnableAutoConfiguration ...

  8. EnableAutoConfiguration注解 Spring中@Import注解的作用和使用

    EnableAutoConfiguration注解 http://www.51gjie.com/javaweb/1046.html springboot@EnableAutoConfiguration ...

  9. SpringBoot+Spring常用注解总结

    为什么要写这篇文章? 最近看到网上有一篇关于 SpringBoot 常用注解的文章被转载的比较多,我看了文章内容之后属实觉得质量有点低,并且有点会误导没有太多实际使用经验的人(这些人又占据了大多数). ...

随机推荐

  1. 1M大概多少个字

    <?php echo strlen("你"); 保存文件为gbk 输出2 保存文件为utf-8 输出3 说明不同编码占用字节不同 1M=1024kB 1KB = 1024B ...

  2. Vue命名规范

    views 命名 views 文件夹下面是由 以页面为单位的vue文件 或者 模块文件夹 组成的,放在 src 目录之下,与 components.assets 同级. views 下的文件夹命名 v ...

  3. 变长数组(variable-length array,VLA)(C99)

    处理二维数组的函数有一处可能不太容易理解,数组的行可以在函数调用的时候传递,但是数组的列却只能被预置在函数内部.例如下面这样的定义: #define COLS 4 int sum3d(int ar[] ...

  4. tomcat下载地址

    https://archive.apache.org/dist/tomcat/tomcat-6/v6.0.53/bin/ Index of /dist/tomcat/tomcat-6/v6.0.53 ...

  5. 【Pet HDU - 4707 】【利用并查集找深度】

    #include<iostream> #include<cstdio> #include<cstring> using namespace std; const i ...

  6. 《老子》是帝王术,提倡复古,崇拜圣人,主张愚民,甘居下流,不争上游:4星|李零《人往低处走:<老子>天下第一》

    ​​“ 俗话说,“人往高处走,水往低处流”.<老子>正好相反,它强调的是作“天下谷”.“天下溪”.“天下之牝”,甘居下流,不争上游(第28和第61章).司马谈说,道家的特点是“去健羡,绌聪 ...

  7. The Shortest Statement(Educational Codeforces Round 51 (Rated for Div.2)+最短路+LCA+最小生成树)

    题目链接 传送门 题面 题意 给你一张有\(n\)个点\(m\)条边的联通图(其中\(m\leq n+20)\),\(q\)次查询,每次询问\(u\)与\(v\)之间的最短路. 思路 由于边数最多只比 ...

  8. The 16th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple (Mirror)

    B题 思路 因为 \[ x=\sum\limits_{k=1}^{n}ka_k\\ y=\sum\limits_{k=1}^{n}ka_{k}^{2} \] 我们设交换前和交换后的这两个等式的值设为\ ...

  9. JavaScript——判断页面是否加载完成

    前言 接上文,既然你是做一个loading的效果,你总不能一直loading,当页面完成加载的时候你总要结束吧 步骤 先说下原生的方法,再讲jquery的方法,原理是一样的 JavaScript // ...

  10. C++报错:全局变量重定义或是多次定义

    如何在C++中定义全局变量时避免重复定义呢? 只要在定义时尽量在.cpp文件中进行,而不要在.h 文件中定义,定义好了之后,可以在.h文件中利用extern关键字进行声明. 如果在.h文件中定义的话, ...