0
点赞
收藏
分享

微信扫一扫

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


文章目录

  • ​​目录:​​
  • ​​一、@EnableAutoConfigration原理概要:​​
  • ​​二、手动添加自动配置类项加载bean​​
  • ​​演示配置·spring.boot.enableautoconfiguration`来增加bean到spring容器中:​​
  • ​​三、禁用自动配置功能​​
  • ​​为什么这样配置就可禁用了?​​
  • ​​四、排除自动配置项的2种方式​​
  • ​​根据类​​
  • ​​也可以按照类名:​​
  • ​​五、springboot提供的自动配置项有哪些​​
  • ​​六、GsonAutoConfiguration注解说明​​
  • ​​七、为什么@EnableAutoConfiguration也可当做配置类来用?​​

目录:

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

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

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

一、@EnableAutoConfigration原理概要:

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

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

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

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


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

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

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


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

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

  • 其内部实现的关键点有:
    1: ImportSelector 该接口的方法的返回值都会被纳入到spring容器中管理
  • springboot原理实战(9)--@EnableAutoConfigration注解使用和原理_spring boot_05

  • 2: SpringFactoriesLoader 该类可以从classpath中搜索所有的所有META-INF/spring.factories 配置文件,并读取配置
  • springboot原理实战(9)--@EnableAutoConfigration注解使用和原理_maven_06


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


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

我们知道了@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​​代码:

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

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​​:

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


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();
}

}

运行结果:

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


因为,

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


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

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

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

再次启动demo6的入口函数:

运行结果如下:

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


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

三、禁用自动配置功能

刚才,我们利用EnableAutoConfiguration的注入bean的配置文件增加了几个我们自己的bean。那么我们怎么这个启用自动注入的功能禁用呢?
很简单:
来操作下:
在demo6的​​​application.properties​​​:
配置如下:

spring.boot.enableautoconfiguration=false

再次测试

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


运行结果:

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


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

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

继续追源码:

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


看下导入的AutoConfigurationImportSelector

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


AutoConfigurationImportSelector类有个方法:

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


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

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

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

看下源码:

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


发现有个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

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


打印:

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


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

也可以按照类名:

改成这样即可:

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


同样可以排除注入的bean。

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

继续看spring.properties

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


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

六、GsonAutoConfiguration注解说明

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

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


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

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

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


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

@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();
}
}

打印结果:

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


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

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

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

@SpringBootApplication一个注解了:

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

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


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

我们去验证我们的答案:

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


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


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

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

个人微信公号:

搜索: 怒放de每一天

不定时推送相关文章,期待和大家一起成长!!

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


举报

相关推荐

0 条评论