springboot原理实战(9)--@EnableAutoConfigration注解使用和原理

简介: springboot原理实战(9)--@EnableAutoConfigration注解使用和原理

目录:


前面了解了@Eanable*前缀注入特性实现的原理,是通过@import按照条件导入spring容器进行管理bean的。

现在了解@EnableAutoConfigration这个特殊的注解,先看本文章的脑图吧:

1dc618a0ed9580ce8bfa6facb208c08f.png


一、@EnableAutoConfigration原理概要:


当然这个注解也是符合enable*前缀注解实现原理的,为啥它比较特殊呢?


主要这个注解导入的类比较多比较强大,很多类都是通过这个注解默认或者按照条件导入的。


这个注解有个属性spring.boot.enableautoconfiguration如下图红框:

5d4c6812c8535adbb050f4ddf2e1bce8.png

这个属性配置了:默认的的注入了很多的类。配置文件在

jar包:spring-boot-autoconfigure-2.2.5.RELEASE.jar!\META-INF\spring.factories这个文件下:

46a9d80a6e05e4e3b19d57a0ee70bcdf.png

默认导入的如此多的类,我们直接使用就可以了。

66ba272a0bfc97be54a5fa679e3d5482.png


其内部实现的关键点有:


1: ImportSelector 该接口的方法的返回值都会被纳入到spring容器中管理

1dc618a0ed9580ce8bfa6facb208c08f.png

2: SpringFactoriesLoader 该类可以从classpath中搜索所有的所有META-INF/spring.factories 配置文件,并读取配置


1dc618a0ed9580ce8bfa6facb208c08f.png5d4c6812c8535adbb050f4ddf2e1bce8.png46a9d80a6e05e4e3b19d57a0ee70bcdf.png


我们知道了@EnableAutoConfigration注入bean的原理,就可用它来做一些例子了。


二、手动添加自动配置类项加载bean


@EnableAutoConfigration\是通过在META-INF\spring.factories配置spring.boot.enableautoconfiguration的值来操作加载bean的,我们也可以在项目中建立META-INF\spring.factories 文件,配置·spring.boot.enableautoconfiguration`来增加bean到spring容器中:


案例:


我们建立2个项目,一个普通的spring项目,一个spirngboot项目,


演示配置·spring.boot.enableautoconfiguration`来增加bean到spring容器中:


普通spring项目core-bean代码:


1dc618a0ed9580ce8bfa6facb208c08f.png


public class Role {
}


@Configuration
public class RunnableConfigration {
    @Bean
    public Runnable createBean(){
        return () -> {};
    }
}


public class User {
}


@Configuration
public class UserConfiguration {
    @Bean
    public User createUser(){
        return new User();
    }
}


spring.factories

暂时啥也不写:

pom.xml


<?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>
    <groupId>com.springboot</groupId>
    <artifactId>core-bean</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>core-bean</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.2.RELEASE</version>
        </dependency>
    </dependencies>
</project>


springboot项目demo6:

1dc618a0ed9580ce8bfa6facb208c08f.png

pom.xml

将core-bean这个包引入到demo6中:

<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>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.springboot</groupId>
            <artifactId>core-bean</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.6</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


@ComponentScan
@EnableAutoConfiguration
public class StudyApplication {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(StudyApplication.class);
        ConfigurableApplicationContext context = app.run(args);
        System.out.println(context.getBean(User.class));
        System.out.println(context.getBean(Role.class));
        System.out.println(context.getBean(Runnable.class));
        context.close();
    }
}


运行结果:

1dc618a0ed9580ce8bfa6facb208c08f.png

因为,

5d4c6812c8535adbb050f4ddf2e1bce8.png

没有加@Component或者@Configration注解:

现在换种方式:修改core-bean的factories的文件:


org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.springboot.corebean.Role,com.springboot.corebean.UserConfiguration,com.springboot.corebean.RunnableConfigration

再次启动demo6的入口函数:

运行结果如下:

46a9d80a6e05e4e3b19d57a0ee70bcdf.png

结果显示我们已经都将bean注入进来了。


三、禁用自动配置功能


刚才,我们利用EnableAutoConfiguration的注入bean的配置文件增加了几个我们自己的bean。那么我们怎么这个启用自动注入的功能禁用呢?

很简单:


来操作下:


在demo6的application.properties:

配置如下:


spring.boot.enableautoconfiguration=false

再次测试

1dc618a0ed9580ce8bfa6facb208c08f.png

运行结果:

5d4c6812c8535adbb050f4ddf2e1bce8.png

这样,就实现了禁用自动注入的功能了。


为什么这样配置就可禁用了?


继续追源码:

46a9d80a6e05e4e3b19d57a0ee70bcdf.png

看下导入的AutoConfigurationImportSelector

66ba272a0bfc97be54a5fa679e3d5482.png

AutoConfigurationImportSelector类有个方法:

88b9988b40447cb37c7e3c492d49867f.png

这个就是是否启用:SPring.boot.enableautoconfiguration属性的,默认的true,第3个参数,默认是启用的。


四、排除自动配置项的2种方式


刚才是将自动配置的功能全部注入,我们实际项目中肯定不会这么用,不然springboot最好用的就被我们给抛弃了,还用springboot干啥。但是我们有排除某个注入的类的需求。


看下源码:

1dc618a0ed9580ce8bfa6facb208c08f.png

发现有个2中方式排除,那么继续做案例:


根据类


public class UserConfiguration {
    @Bean
    public User createUser(){
        return new User();
    }
}


spring.factories


org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.springboot.corebean.Role,com.springboot.corebean.UserConfiguration,com.springboot.corebean.RunnableConfigration

5d4c6812c8535adbb050f4ddf2e1bce8.png

打印:

46a9d80a6e05e4e3b19d57a0ee70bcdf.png

说明user没有被注入进去,我们已经把他排除了。


也可以按照类名:


改成这样即可:

1dc618a0ed9580ce8bfa6facb208c08f.png

同样可以排除注入的bean。


五、springboot提供的自动配置项有哪些


继续看spring.properties


5d4c6812c8535adbb050f4ddf2e1bce8.png46a9d80a6e05e4e3b19d57a0ee70bcdf.png


六、GsonAutoConfiguration注解说明


我们来瞅一个,我们熟悉的gson:看下他怎么注入的:

1dc618a0ed9580ce8bfa6facb208c08f.png

看到了我们之前学过得condition接口的实现类,表示没有gson的时候,这个GsonAutoConfigiguration才生成。一个。有的化就不注入了。


而且我们还能看出来,并不是EnableAutoConfiguration这个注解的spring.boot.enableautoconfiguration属性配置了就一定注入到spring。他可以结合condition和conditional注解来条件话选择注入。


现在我们测试下,spring帮我们注入gson了不?

5d4c6812c8535adbb050f4ddf2e1bce8.png

@ComponentScan
@EnableAutoConfiguration
public class StudyApplication {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(StudyApplication.class);
        ConfigurableApplicationContext context = app.run(args);
        System.out.println(context.getBeansOfType(Gson.class));
        context.close();
    }
}


打印结果:

1dc618a0ed9580ce8bfa6facb208c08f.png

跟我们分析的源码一致,在我们没注入的情况下,GsonAutoConfigiguration帮我们自动注入Gson对象了。


七、为什么@EnableAutoConfiguration也可当做配置类来用?


将一个bean当做一个配置类并启用的注解是:@EnableConfigurationProperties,但是入口函数:


@SpringBootApplication一个注解了:


这个类里没有@EnableConfigurationProperties,只有@EnableAutoConfiguration,为啥就能启用配置类了?

5d4c6812c8535adbb050f4ddf2e1bce8.png

原理其实今天已经讲了:肯定是@EnableAutoConfiguration中的属性中有这个@EnableConfigurationProperties项,

我们去验证我们的答案:

46a9d80a6e05e4e3b19d57a0ee70bcdf.png66ba272a0bfc97be54a5fa679e3d5482.png


所以@EnableAutoConfiguration自动注入了@EnableConfigurationProperties,也就能实现启用配置类的作用了。


总结:本文主要讲了@EnableAutoConfigration注解使用和原理,就是通过一个spring.properties文件来实现按条件注入bean的,可以全局禁用自动配置,也可以按照类或者类名从spring容器中剔除某个类的管理,还说了常用的GsonAutoConfiguration是如何帮我们自动注入一个Gson对象的,以及了解了为什么@EnableAutoConfiguration也可当做配置类来用。


相关文章
|
3月前
|
XML Java 测试技术
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
265 26
|
2月前
|
缓存 NoSQL Java
基于SpringBoot的Redis开发实战教程
Redis在Spring Boot中的应用非常广泛,其高性能和灵活性使其成为构建高效分布式系统的理想选择。通过深入理解本文的内容,您可以更好地利用Redis的特性,为应用程序提供高效的缓存和消息处理能力。
187 79
|
4月前
|
缓存 Java 数据库
SpringBoot缓存注解使用
Spring Boot 提供了一套方便的缓存注解,用于简化缓存管理。通过 `@Cacheable`、`@CachePut`、`@CacheEvict` 和 `@Caching` 等注解,开发者可以轻松地实现方法级别的缓存操作,从而提升应用的性能和响应速度。合理使用这些注解可以大大减少数据库的访问频率,优化系统性能。
244 89
|
1月前
|
缓存 安全 Java
深入解析HTTP请求方法:Spring Boot实战与最佳实践
这篇博客结合了HTTP规范、Spring Boot实现和实际工程经验,通过代码示例、对比表格和架构图等方式,系统性地讲解了不同HTTP方法的应用场景和最佳实践。
136 5
|
2月前
|
Java Spring
SpringBoot自动配置原理
本文深入解析了SpringBoot的核心功能——自动配置,重点探讨了`org.springframework.boot.autoconfigure`及相关注解的工作机制。通过分析`@SpringBootApplication`、`@EnableAutoConfiguration`等注解,揭示了SpringBoot如何基于类路径和条件自动装配Bean
92 7
|
2月前
|
JSON 前端开发 Java
Spring MVC常用的注解
@RequestMapping:用于处理请求 url 映射的注解,可用于类或方法上。用于类上,则表示类中 的所有响应请求的方法都是以该地址作为父路径。 @RequestBody:注解实现接收http请求的json数据,将json转换为java对象。 @ResponseBody:注解实现将conreoller方法返回对象转化为json对象响应给客户。 @Controller:控制器的注解,表示是表现层,不能用用别的注解代替 @RestController : 组合注解 @Conntroller + @ResponseBody @GetMapping , @PostMapping , @Put
|
3月前
|
Java Spring
SpringBoot 实战 不同参数调用不同实现
本文介绍了如何在实际工作中根据不同的入参调用不同的实现,采用`map+enum`的方式实现优雅且严谨的解决方案。通过Spring Boot框架中的工厂模式或策略模式,避免了使用冗长的`if...else...`语句。文中详细展示了定义接口、实现类、枚举类以及控制器调用的代码示例,确保用户输入的合法性并简化了代码逻辑。
SpringBoot 实战 不同参数调用不同实现
|
2月前
|
Java Spring
Spring Boot的核心注解是哪个?他由哪几个注解组成的?
Spring Boot的核心注解是@SpringBootApplication , 他由几个注解组成 : ● @SpringBootConfiguration: 组合了- @Configuration注解,实现配置文件的功能; ● @EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项 ● @ComponentScan:Spring组件扫描
|
2月前
|
Java
SpringBoot自动装配的原理
在SpringBoot项目的启动引导类上都有一个注解@SpringBootApplication 这个注解是一个复合注解, 其中有三个注解构成 , 分别是 ● @SpringBootConfiguration : 是@Configuration的派生注解 , 标注当前类是一个SpringBoot的配置类 ● @ComponentScan : 开启组件扫描, 默认扫描的是当前启动引导了所在包以及子包 ● @EnableAutoConfiguration : 开启自动配置(自动配置核心注解) 2.在@EnableAutoConfiguration注解的内容使用@Import注解导入了一个AutoC
|
2月前
|
Java 测试技术 Spring
SpringBoot+@Async注解一起用,速度提升
本文介绍了异步调用在高并发Web应用性能优化中的重要性,对比了同步与异步调用的区别。同步调用按顺序执行,每一步需等待上一步完成;而异步调用无需等待,可提升效率。通过Spring Boot示例,使用@Async注解实现异步任务,并借助Future对象处理异步回调,有效减少程序运行时间。