目录
一、什么是springboot的自动配置?
Spring Boot通过@EnableAutoConfiguration注解开启自动配置,对autoconfigured的jar包下的META-INF下的spring包中下的spring.factories文件进行扫描,这个文件中包含了可以进行自动配置的类,当满足@Condition注解指定的条件时,便在依赖的支持下进行实例化,注册到Spring容器中。
用注解来对一些常规的配置做默认配置,简化了各种xml配置内容,使项目能够快速运行。自动装配最明显的特征就是不用xml文件去做配置,而是用到properties文件或者yml文件,在pom.xml中简单地写一些坐标就能实现各类负载地配置。自动将Bean装配到IOC容器中
二、@Enable注解
//MyImportSelector
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
//目前字符串数组内容是写死的,未来可以设置在配置文件中动态加载
return new String[]{"com.apesource.springbootenableother04.domain.User","com.apesource.springbootenableother04.domain.Student"};
}
}
//MyImportBeanDefinitionRegistrar
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//AnnotationMetadata注解
//BeanDefinitionRegistry向spring容器中注入
//获取user的definition对象
AbstractBeanDefinition beanDefinition= BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();
//通过beanDefinition属性信息,向Spring容器中注册id为user的对象
registry.registerBeanDefinition("user",beanDefinition);
}
}
//UserConfig
@Configuration
public class UserConfig {
@Bean
public User user(){
return new User();
}
}
//EnableUser
@Target(value = ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(UserConfig.class)
public @interface EnableUser {
}
三、springboot自动配置流程
springboot的启动类main方法上有一个springboot的核心注解@SpringbootApplication
按ctrl点进去
@ComponentScan
@SpringBootConfiguration
![](https://i-blog.csdnimg.cn/direct/4835ea0cce4240319a930ab8a71edf79.png)
@EnableAutoConfiguration注解
主要作用是开启自动配置
而@EnableAutoConfiguration也是一个复合注解,它包含了@AutoConfigurationPackage和@Import({AutoConfigurationImportSelector.class})。
@AutoConfigurationPackage注解,自动配置包。点进去可以看到就是⼀个 @Import 注解:@Import(Registrar.class) ,导⼊了⼀个Registrar 的组件,这个注解的作用就是将主配置类(@SpringBootConfiguration标注的类)所在的包及其下面所有子包里面所有的组件扫描到IOC容器中。
而@Import(AutoConfigurationImportSelector.class)注解通过@Import导入了AutoConfigurationImportSelector类,而这个类的selectImports方法会通过SpringFactoriesLoader(这个类实现了检索META-INF/spring.factories文件,并获取指定接口的配置的功能)得到大量的配置类,当 SpringBoot 应用启动时,会自动加载这些配置类,初始化Bean 。而每个配置类则根据条件化配置类做出决策,以实现自动配置的功能。
-
SpringFactoriesLoader
机制:Spring Boot 在META-INF/spring.factories
文件中定义了自动配置类的列表。在启动时,通过SpringFactoriesLoader
加载这些配置类,并根据条件进行处理。
我们写配置类只需要加入一个@Configuration注解,Springboot就可以轻松地自己找到想要地目标文件。
并不是所有的Bean都会被初始化,需要在配置类中使用Condition来加载满足条件的Bean
condition的几个注解:
ConditionalOnProperty:用来判断配置文件中是否有对应属性和值才初始化Bean
ConditionalOnClass:用来判断环境中是否有对应字节码文件才初始化Bean
ConditionalOnMissingBean:用来判断环境中没有对应Bean才初始化Bean
ConditionalOnBean:用来判断环境中有对应Bean才初始化Bean
Spring Boot 的 自动配置流程大致如下:1. 启动应用:当运行 Spring Boot 应用时,首先会 加载主启动类。2. 依赖解析:Spring Boot 会检查项目中引入的依赖。3. 加载 `spring.factories` 文件:查找并加载 `META-INF/spring.factories` 文件,该文件中定 义了各种自动配置类。4. 条件判断:对于每个自动配置类,根据条件注解(如 `@ConditionalOnClass`、 `@ConditionalOnProperty` 等)进行判断。- 如果条件满足,相关的配置类会被加载。- 如果条件不满足,则跳过该配置。5. 配置生效:满足条件的配置类中的配置逻辑被执行,完成相关组件的自动配置。6. 应用上下文准备:将自动配置好的组件注册到 Spring 应用上下文 (ApplicationContext) 中,使其可供应用使用。7. 启动完成:完成自动配置和组件注册后,应用启动完成,开始处理业务逻辑。例如,如果项目中添加了数据库相关的依赖,并且配置文件中提供了正确的数据库连接信息,那么相应的数据库自动配置类会在条件满足的情况下被加载和执行,完成数据库连接池等的配置。
四、自定义启动类
需求:
参考:
实现步骤:
![](https://i-blog.csdnimg.cn/direct/5ab66a5901084f30934ebeea415f3d9f.png)
![](https://i-blog.csdnimg.cn/direct/2d465f3e9f214520a6b647e732449cb4.png)
<!--引入自定义的redis-spring-boot-autoconfigure-->
<dependency>
<groupId>com.apesource</groupId>
<artifactId>redis-spring-boot-autoconfigure</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--引入jedis依赖-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
spring.factories文件:
根据springboot自动配置的过程,我们手动的配置了一个spring.factories用来设置自动加载类是谁
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.apesource.RedisAutoconfiguration
RedisProperties类:(定义主机和端口号)
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {
private String host="localhost";
private int port=6379;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
}
这里面的@ConfigurationProperties(prefix = "spring.redis")用于将外部配置文件,就比如 application.properties 或 application.yml中的配置参数绑定到这个类的字段上。
host是Redis服务器的主机名,port是于存储 Redis 服务器的端口号。
RedisAutoConfiguration类:(配置类)
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.Jedis;
@Configuration
@EnableConfigurationProperties(RedisProperties.class)
public class RedisAutoconfiguration {
//注入jedis
@Bean
public Jedis jedis(RedisProperties redisProperties){
return new Jedis(redisProperties.getHost(), redisProperties.getPort());
}
}
加了@EnableConfigurationProperties(RedisProperties.class)注解用于对对 RedisProperties 配置属性类的支持。RedisProperties 是一个包含了 Redis 配置参数的类,通常包括主机名、端口等。通过这个注解,Spring Boot 可以将外部配置文件(如 application.properties 或 application.yml)中的相关配置映射到 RedisProperties 类的属性中,并自动实例化一个 RedisProperties 对象。
<!--引入自定义的redis-spring-boot-starter模块-->
<dependency>
<groupId>com.apesource</groupId>
<artifactId>redis-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
properties.yml文件中自定义配置redis的主机和端口号
spring:
redis:
host: 127.0.0.1
port: 6060
测试类:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import redis.clients.jedis.Jedis;
@SpringBootApplication
public class SpringbootStarter04Application {
public static void main(String[] args) {
ConfigurableApplicationContext context=SpringApplication.run(SpringbootStarter04Application.class, args);
Jedis bean1=context.getBean(Jedis.class);
System.out.println(bean1);
}
}
运行结果: