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