SpringBoot自动配置原理和自定义启动器

2023-12-30 20:27:09
1、自动配置的原理

项目在加载上下文时,会根据@SpringBootApplication注解运行。该注解中有一个@CompoentScan注解,会扫描和加载当前启动类所在的目录,以及所有的子目录;还有一个是@EnableAutoConfiguration注解,这个注解会读取扫描到META-INF/spring.factories文件,这个文件里面定义了100多个自动装配依赖的配置类。 尽管能够全部读取到这些配置类,但并不会全部加载这些类以及创建类对象, 而是要根据@ConditionOnClass注解来做决定。ConditionOnClass注解会判断当前配置类对应启动器是否有添加,如果添加了启动器,就说明添加了对应的依赖,就会创建对应的配置类。

  • @CompoentScan注解,扫描文件,重点是扫描到META-INF/spring.factories文件;
  • @EnableAutoConfiguration注解,读取META-INF/spring.factories文件内容;
  • @ConditionOnClass注解, 拍板决定是否要创建META-INF/spring.factories文件里的某个配置类。

2、自定义启动器,实现自动配置

编写自动配置的自定义启动器的逻辑是,编写好默认的配置属性和配置类,以及根据配置类创建对应的对象,然后将对象交给Spring容器管理。其他人在引入启动器后,就可以直接注入核心对象使用。

(1) 项目目录结构

(2) 引入pom依赖
<dependencies>
  <!--jedis依赖-->
  <dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
  </dependency>
  <!--启动器依赖-->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
  </dependency>
  <!--lombok依赖-->
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
  </dependency>
</dependencies>

(3) 创建初始化的属性值对象
package com.zhuimengren.myjedis.conf;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * jedis属性类
 */
@Data
@ConfigurationProperties(prefix = "my-jedis")
public class MyJedisProperties {
    /**
     * redis的IP地址
     */
    private String host = "localhost";

    /**
     * redis端口号
     */
    private Integer port = 6379;

    /**
     * redis的最大连接数
     */
    private Integer maxActive = 8;

    /**
     * redis的请求超时最大等待时间
     */
    private Long maxWait = -1L;
}

(4) 创建默认的配置类
package com.zhuimengren.myjedis.conf;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

@Configuration // 标识当前是一个配置类
@ConditionalOnClass(MyJedisProperties.class) // 判断开发的项目是否引用了启动器中的类,引用了才会执行当前配置类的代码
@EnableConfigurationProperties(MyJedisProperties.class) // 开启设置JedisProperties类读取配置文件中的数据
public class MyJedisAutoConfiguration {

    @Autowired
    private MyJedisProperties myJedisProperties;

    private JedisPool jedisPool;

    public MyJedisAutoConfiguration(){
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(myJedisProperties.getMaxActive());
        config.setMaxWaitMillis(myJedisProperties.getMaxWait());
        jedisPool = new JedisPool(config,myJedisProperties.getHost(), myJedisProperties.getPort());
    }

    /**
     * 创建Jedis对象,加入IOC容器
     */
    public Jedis jedis(){
        return jedisPool.getResource();
    }

}

(5) 扫描配置类,交给spring容器管理

注意:如果某个类没有放在在启动类的包及其子包下,要想运行就可以将该类添加到META-INF/spring.factories文件

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.zhuimengren.myjedis.conf.MyJedisAutoConfiguration

文章来源:https://blog.csdn.net/qq_45110186/article/details/135308637
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。