springboot自动配置原理以及手动实现配置类

1、原理

spring有一个思想是“约定大于配置”。

配置类自动配置可以帮助开发人员更加专注于业务逻辑开发,springboot在启动的时候可以把一些配置类自动注入到spring的IOC容器里,项目运行之后就可以直接使用这些配置类的属性和方法等。

springboot有一个全局配置文件,application.properties / application.yml,各种属性都可以在文件中进行自定义配置。

自动配置实现原理:

我们都知道项目的入口是 @SpringBootApplication 注解,这个注解标识了该类是springboot的启动类,那我们就从它入手一探究竟。

我们可以看到这个注解是一个复合注解,其中的 @EnableAutoConfiguration 注解表示开启自动配置,这个注解也是复合注解。

我们可以看到它导入了一个名为AutoConfigurationImportSelector的类,那么这个类的作用是什么呢?

我们继续往下看,可以看到 selectImports( ) 方法

selectImports 这个方法通过调用 SpringFactoriesLoader.loadFactoryNames() 方法扫描spring-boot-autoconfigure-xxx.jar/META-INF路径下的 spring.factories文件,通过类的全路径拿到需要配置的类名,然后通过反射将其全部注入IOC容器中。

每个配置类都有一些属性,XXXAutoConfiguration自动配置类,会有一个@EnableConfigurationProperties注解,它的参数是一个XXXProperties类,该注解的作用是把XXXProperties类的实例加载到Spring的IOC容器中,而XXXProperties类中的属性就是自动配置的属性。

XXXProperties类有一个注解@ConfigurationProperties,该注解可以扫描全局配置文件application.properties或者application.yml文件中以prefix开头的一组配置绑定到DataSourceProperties实例的属性上,实现自动配置。

// 全局扫描注入 配置文件中以spring.datasource开头的值
@ConfigurationProperties(
prefix = "spring.datasource"
)

2、手动写一个自动配置类

有了上面的理解,我们可以自己动手写一个自动配置类。

自动配置类做的事情就是把@EnableConfigurationProperties注解标识的类注入到IOC容器。

2.1、所以我们先写一个自动配置类SeviceAutoConfiguration

package com.ycw.autoconfig.configuration;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration; /**
* @author Administrator
* @date 2022-09-30 21:51
*/
@Slf4j
@Configuration // 自动配置类
@EnableConfigurationProperties(ServiceProperties.class) // 标识XXXProperties类的实例
public class SeviceAutoConfiguration { }

2.2、写真正要加入容器的类ServiceProperties

package com.ycw.autoconfig.configuration;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties; /**
* @author Administrator
* @date 2022-09-30 21:50
*/
@Data
@Slf4j
@ConfigurationProperties(prefix = "myconfig") // 扫描全局配置文件完成属性注入
public class ServiceProperties {
private String name;
public void print(){
log.info("自动配置成功! " + name);
}
}

2.3、在resources目录下新建目录META-INF,新建文件spring.factories完成对自动配置类全路径配置

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.ycw.autoconfig.configuration.SeviceAutoConfiguration

2.4、在全局配置文件application.properties中添加属性注入

2.5、写一个Controller测试,ControllerTest

package com.ycw.autoconfig.controller;

import com.ycw.autoconfig.configuration.ServiceProperties;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; /**
* @author Administrator
* @date 2022-09-30 21:54
*/
@RestController
public class ControllerTest {
@Resource
private ServiceProperties serviceProperties;
@RequestMapping("test")
public void test(){
serviceProperties.print();
}
}

运行之后我们可以看到:

分析一下这个过程:

  1. 启动类@SpringBootApplication通过spring.factories文件中的org.springframework.boot.autoconfigure.EnableAutoConfiguration找到了SeviceAutoConfiguration

  2. @Configuration 注解的类SeviceAutoConfiguration被springboot扫描到后,它所标识的@EnableConfigurationProperties(ServiceProperties.class) 开始进入被注入容器的过程

  3. ServiceProperties 类的注解@ConfigurationProperties(prefix = "myconfig") 使得springboot扫描全局配置文件application.properties

  4. application.properties中的 myconfig.name=yangchuanwei 被注入到属性name中,自此ServiceProperties已经被自动配置成功!


获取demo地址可以关注公众号【靠谱杨的挨踢生活】,回复【autoconfig】获取下载链接。

最新文章

  1. C++ 11 多线程--线程管理
  2. renderman、arnold及全局光照
  3. ios 利用size classes 使 iPad  水平和垂直方向布局不同
  4. webshell
  5. Xcode7企业版打包
  6. JS 中的foreach和For in比较
  7. 如何在makefile中写cd命令
  8. 基于ADL5317的雪崩光电二极管(APD)偏压控制/光功率监测电路的设计
  9. 《转》---使用递归方法DataTable 绑定 TreeView
  10. php部分---面向对象,设计模式(单例模式、工厂模式)、oop六大原则;
  11. java15 IO装饰设计模式
  12. SQL每个用户最后的一条记录
  13. Python IDLE 快捷键
  14. hdu 1429 胜利大逃亡(延续)(BFS+比特压缩)
  15. HTTP网络协议与手写Web服务容器
  16. bind、call和apply对比和使用
  17. Linux 下源码编译FFMEG
  18. flyway和liquibase的使用样例
  19. CH2601 电路维修(算竞进阶习题)
  20. 逆元(inv)

热门文章

  1. Rails_via牛客网
  2. 使用SSH连接解决git报错:fatal: unable to access 'https://github.com/xxx/xxx.github.io.git/': Proxy CONNECT aborted
  3. LuoguP5201 [USACO19JAN]Shortcut(最短路树)
  4. HDU3085 Nightmare Ⅱ (双向BFS)
  5. Java源码分析 | CharSequence
  6. React的生命周期函数
  7. 禁止mysql自动更新
  8. HiveSql调优系列之Hive严格模式,如何合理使用Hive严格模式
  9. HCNP Routing&Switching之IP安全
  10. std::atomic和std::mutex区别