springboot的自动配置实现方式

Spring Boot的自动配置是指Spring Boot根据应用程序的依赖和配置信息,自动为应用程序进行配置,减少了开发人员手动配置的工作量。

Spring Boot的自动配置基于条件注解和Spring Boot Starter的机制。条件注解是通过判断一定的条件是否满足来决定是否应用某个配置。Spring Boot Starter是一种特殊的依赖,它包含了一组相关的依赖和配置,可以通过引入该Starter来自动配置相关的功能。

Spring Boot的自动配置可以通过以下几种方式实现:

                  1. 使用@EnableAutoConfiguration注解

2. 使用@ConfigurationProperties注解

3. 使用@Conditional注解

4. 使用Spring Boot Starter自定义配置


1. 使用@EnableAutoConfiguration注解

在Spring Boot的主配置类上添加@EnableAutoConfiguration注解,Spring Boot会根据类路径上的依赖自动进行配置。@Enable底层依赖于@Import注解导入一些类,使用@Import导入的类会被Spring加载到IOC容器中。而@Import提供4中用法: 

  • ​    ① 导入Bean 
  • ​    ② 导入配置类 
  • ​    ③ 导入 ImportSelector 实现类。一般用于加载配置文件中的类 
  • ​    ④ 导入 ImportBeanDefinitionRegistrar 实现类。     

@SpringBootApplication注解内部

  @SpringBootConfiguration
  @EnableAutoConfiguration
  @ComponentScan(
      excludeFilters = {@Filter(
      type = FilterType.CUSTOM,
      classes = {TypeExcludeFilter.class}
  ), @Filter(
      type = FilterType.CUSTOM,
      classes = {AutoConfigurationExcludeFilter.class}
  )}
  )
  public @interface SpringBootApplication {
      // ......
  }

@ComponentScan

  这个注解在Spring中很重要 ,它对应XML配置中的元素。

  作用:自动扫描并加载符合条件的组件或者bean , 将这个bean定义加载到IOC容器中

@SpringBootConfiguration

  作用:SpringBoot的配置类 ,标注在某个类上 , 表示这是一个SpringBoot的配置类;

//@SpringBootConfiguration注解内部
  //这里的 @Configuration,说明这是一个配置类 ,配置类就是对应Spring的xml 配置文件;
  @Configuration
  public @interface SpringBootConfiguration {}
  //里面的 @Component 这就说明,启动类本身也是Spring中的一个组件而已,负责启动应用
  @Component
  public @interface Configuration {}

@AutoConfigurationPackage :自动配置包

//AutoConfigurationPackage的子注解
//Registrar.class 作用:将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring容器 
@Import({Registrar.class})
public @interface AutoConfigurationPackage {
}

@EnableAutoConfiguration开启自动配置功能

以前我们需要自己配置的东西,而现在SpringBoot可以自动帮我们配置 ;需要告诉SpringBoot开启自动配置功能,这样自动配置才能生效;

@Import({AutoConfigurationImportSelector.class}) :给容器导入组件 

@AutoConfigurationImportSelector :自动配置导入选择器,给容器中导入一些组件

AutoConfigurationImportSelector.class
            ↓
    selectImports方法
            ↓
this.getAutoConfigurationEntry(annotationMetadata)方法
            ↓
this.getCandidateConfigurations(annotationMetadata, attributes)方法
            ↓
方法体:
 List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
        Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
        return configurations;
            ↓
在所有包名叫做autoConfiguration的包下面都有META-INF/spring.factories文件

总结原理:

- @EnableAutoConfiguration 注解内部使用                             

-@Import(AutoConfigurationImportSelector.**class**)来加载配置类。 
- 配置文件位置:META-INF/spring.factories,该配置文件中定义了大量的配置类,当 SpringBoot 应用启动时,会自动加载这些配置类,初始化Bean 
- 并不是所有的Bean都会被初始化,在配置类中使用Condition来加载满足条件的Bean

2. 使用@ConfigurationProperties注解

通过在配置类中使用@ConfigurationProperties注解,可以将配置文件中的属性值自动绑定到配置类的属性上。以导入Redis为例

RedisProperties

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

主配置类中自动加载RedisProperties

@Configuration
@EnableConfigurationProperties(RedisProperties.class)
public class RedisAutoconfiguration {
    //注入jedis
    //@ConditionalOnBean
    @Bean
    public Jedis jedis(RedisProperties redisProperties){
        return new Jedis(redisProperties.getHost(),redisProperties.getPort());
    }
}

3. 使用@Conditional注解

通过在配置类或Bean上使用@Conditional注解,可以根据条件来决定是否应用某个配置或创建某个Bean。

- ConditionalOnProperty:判断配置文件中是否有对应属性和值才初始化Bean 
- ConditionalOnClass:判断环境中是否有对应字节码文件才初始化Bean 
- ConditionalOnMissingBean:判断环境中没有对应Bean才初始化Bean
- ConditionalOnBean:判断环境中有对应Bean才初始化Bean

 以导入Jedis坐标后创建Bean为例,基本思路是:判断redis.clients.jedis.Jedis.class文件是否存在

  • 首先创建一个User类,可以是空类;
  • 其次创建ClassCondition继承自Condition
  • public class ClassCondition  implements Condition {
        /**
         *
         * @param context 上下文对象。用于获取环境,IOC容器,ClassLoader对象
         * @param metadata 注解元对象。 可以用于获取注解定义的属性值
         * @return
         */
    
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            //1.需求: 导入Jedis坐标后创建Bean
            //思路:判断redis.clients.jedis.Jedis.class文件是否存在
            boolean flag = true;
            try{
                Class<?> cls = Class.forName("redis.clients.jedis.Jedis");
            } catch (ClassNotFoundException e) {
                flag = false;
            }
            return flag;
        }
    }
  • 将ClassCondition加入主配置类
  • @Configuration
    public class UserConfig {
    
        @Bean
        @Conditional(value = ClassCondition.class)
        public User user(){
            return new User();
        }
    }
    
  • 测试
  • @SpringBootApplication
    public class DemoApplication {
    
        public static void main(String[] args) {
            ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
            //获取Bean,redisTemplate
            //情况1 没有添加坐标前,发现为空
            //情况2 有添加坐标前,发现有对象
    //        Object redisTemplate = context.getBean("redisTemplate");
    //        System.out.println(redisTemplate);
    
            /********************案例1********************/
            Object user = context.getBean("user");
            System.out.println(user);
        }
    
    }

4. 使用Spring Boot Starter自定义配置

通过引入Spring Boot Starter依赖,可以自动配置相关的功能。例如,引入spring-boot-starter-web依赖可以自动配置Web应用程序所需的相关功能。可以在模块中引入自定义的配置。

        <!--引入自定义的redis-spring-boot-autoconfigure-->
        <dependency>
            <groupId>com.apesource</groupId>
            <artifactId>redis-spring-boot-autoconfigure</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

实现步骤

- 创建redis-spring-boot-autoconfigure模块
- 创建redis-spring-boot-starter模块,依赖redis-spring-boot-autoconfigure的模块
- 在redis-spring-boot-autoconfigure模块中初始化Jedis的Bean,并定义META-INF/spring.factories文件
- 在测试模块中引入自定义的redis-starter依赖,测试获取Jedis的Bean,操作redis。
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值