一:原理

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. js switch case 判断的是绝对相对===,值和类型都要相等

    js switch case 判断的是绝对相对===,值和类型都要相等

  2. MyBatis 中如何调用 Java 的 enum (枚举) 字段

    事先作成一 enum,如下: public enum CityCode { ALL("000"), BEIJING("010"), SHANGHAI(" ...

  3. CentOS7安装VNC

    #安装 yum -y install tigervnc-server 将配置表复制到etc .service 修改配置文件 vim /etc/systemd/system/vncserver@\:.s ...

  4. Python_类的私有属性、私有方法

    1.私有属性:只需要在初始化时,在属性名前加__ class Cup: #构造函数,初始化属性值 def __init__(self,capacity,color): #私有属性,只需要在属性名字前加 ...

  5. MongoDB CPU利用率很高,怎么破(转)

    经常有用户咨询:MongoDB CPU 利用率很高,都快跑满了,应该怎么办? 遇到这个问题,99.9999% 的可能性是「用户使用上不合理导致」,本文主要介绍从应用的角度如何排查 MongoDB CP ...

  6. CSS选择器知识梳理

    <一>CSS选择器结构逻辑图 温馨提示:各位小伙伴,可以把逻辑图下载下来放大,看的比较清除,也可以给我留言,我分享原百度脑图给各位小伙伴. <二>接下来按照结构逻辑图具体讲解各 ...

  7. moviepy的常见用法

    看了,还是自己弄这些方便. #字幕 >>> from moviepy.video.tools.subtitles import SubtitlesClip >>> ...

  8. python笔记36-装饰器之wraps

    前言 前面一篇对python装饰器有了初步的了解了,但是还不够完美,领导看了后又提出了新的需求,希望运行的日志能显示出具体运行的哪个函数. __name__和doc __name__用于获取函数的名称 ...

  9. 51nod 2500 后面第一个大于

    小b有一个长度为n的序列t,现在她对于每个i,求最小的正数j满足i+j≤ni+j≤n且ti+j>titi+j>ti,输出j,如果不存在这样的j,则输出0. 样例解释: 对于i=1,t2&g ...

  10. PS——使用切片工具切出透明图片

    前言 最近有点烦,不说话~ 步骤 首先要保证您的格式为PSD且底色为透明 参考线 标出参考线,方便后面划分 切图 保存 效果