• 007 SpringBoot的@EnableAutoConfiguration注解


    一:原理

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

    1 @Target(ElementType.TYPE)
    2 @Retention(RetentionPolicy.RUNTIME)
    3 @Documented
    4 @Import(EnableConfigurationPropertiesImportSelector.class)
    5 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

     1 package com.jun.enableautoconfiguration;
     2 
     3 import org.springframework.beans.factory.annotation.Autowired;
     4 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
     5 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
     6 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
     7 import org.springframework.boot.context.properties.EnableConfigurationProperties;
     8 import org.springframework.context.annotation.Bean;
     9 import org.springframework.context.annotation.Configuration;
    10 
    11 @Configuration        //为带有@ConfigurationProperties注解的Bean提供有效的支持。
    12                       // 这个注解可以提供一种方便的方式来将带有@ConfigurationProperties注解的类注入为Spring容器的Bean。
    13 @EnableConfigurationProperties(HelloProperties.class)       //开启属性注入,通过@autowired注入
    14 @ConditionalOnClass(Hello.class)           //判断这个类是否在classpath中存在,如果存在,才会实例化一个Bean
    15 @ConditionalOnProperty(prefix="hello", value="enabled", matchIfMissing = true)
    16 public class HelloAutoConfiguration {
    17 
    18     @Autowired
    19     private HelloProperties helloProperties;
    20 
    21     @Bean
    22     @ConditionalOnMissingBean(Hello.class)//容器中如果没有Hello这个类,那么自动配置这个Hello
    23     public Hello hello() {
    24         Hello hello = new Hello();
    25         hello.setMsg(helloProperties.getMsg());
    26         return hello;
    27     }
    28 
    29 }

    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

     1 package com.jun.web;
     2 
     3 import com.jun.enableautoconfiguration.Hello;
     4 import org.slf4j.Logger;
     5 import org.slf4j.LoggerFactory;
     6 import org.springframework.beans.factory.annotation.Autowired;
     7 import org.springframework.boot.SpringApplication;
     8 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
     9 import org.springframework.boot.autoconfigure.SpringBootApplication;
    10 import org.springframework.context.ConfigurableApplicationContext;
    11 import org.springframework.core.env.ConfigurableEnvironment;
    12 import org.springframework.web.bind.annotation.RequestMapping;
    13 import org.springframework.web.bind.annotation.RestController;
    14 
    15 @SpringBootApplication
    16 @EnableAutoConfiguration
    17 @RestController
    18 public class WebApplication {
    19     private static final Logger logger = LoggerFactory.getLogger(WebApplication.class);
    20 
    21     @Autowired
    22     private Hello hello;
    23 
    24     @RequestMapping("/")
    25     public String index() {
    26         return hello.sayHello();
    27     }
    28 
    29     public static void main(String[] args) {
    30         ConfigurableApplicationContext context = SpringApplication.run(WebApplication.class, args);
    31         ConfigurableEnvironment environment = context.getEnvironment();
    32         logger.info("hello.msg:{}",environment.getProperty("hello.msg"));
    33 
    34     }
    35 
    36 }
  • 相关阅读:
    opengl中的阴影映射
    怎样实现全屏显示(vc)
    刚花了10800大元买了一台IBM ThinkPad T60 dh2(港行水货)
    64位进程调用32位dll的解决方法
    转贴: OpenGL开发库的组成
    64位程序编译:终于将City****由32位编译为64位了
    opengl中的阴影体
    [转贴+更新]关于Directshow SDK 和Windows SDK
    安全专家称不再向厂商免费提供漏洞信息 狼人:
    国图新馆暴发网络病毒 来源或为读者自带笔记本 狼人:
  • 原文地址:https://www.cnblogs.com/juncaoit/p/11393422.html
Copyright © 2020-2023  润新知