SpringBoot的自动配置实现和介绍

自动配置实现逻辑 --> 约定大于配置

在spring4.0时提出了Condition相关注解,Condition相关注解可以让用户提供一个判断条件,从而返回true和false,进而通过返回值类型决定对象是否能够初始化或者说注入到spring容器。

在springboot中判断条件一般为starters中的相关类。

原生注解:

我们写一个案例,内容:加入redis包存在我们注入一个User类,模拟一下自动配置Redis。然后再启动类中取一下

@Configuration
public class UserConfig {
    @Bean
    @Conditional(MyCondition.class) //原生注解
    public User user() {
        User user = new User();
        user.setUsername("武大郎");
        user.setId(1);
        return user;
    }
}

class MyCondition implements Condition {

    /*
        根据当前环境中是否有RedisTemplate决定user bean 是否注入

        RedisTemplate---取决于是否导入了redis starters
     */

    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        boolean flag = true;
        try {
            Class<?> aClass = Class.forName("org.springframework.data.redis.core.RedisTemplate");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            flag = false;
        }
        return flag;
    }
}

启动测试类运行一下,看一下结果

@SpringBootApplication
@MapperScan("com.zys.springboot01.mapper")
public class Springboot01Application {

    public static void main(String[] args) {
        ConfigurableApplicationContext applicationContext = SpringApplication.run(Springboot01Application.class, args);
        Object user = applicationContext.getBean("user");
        System.out.println("获取对象: " + user);
    }
..............

结果

 使用反射去查看redis包是否存在,而重写的 matches() 方法返回值若为false则不加载User类,反之则加载,若搭配if判断就模拟了一个简单的自动配置。

衍生注解/派生注解


@Configuration //声明是一个配置

public class UserConfig {

/*
    @Bean
    public Apple apple(){
        return new Apple();
    }
*/


    @Bean
    //@Conditional(MyCondition.class) //原生注解
    /*
        判断当前环境中是否有Apple Bean,如果有返回true, 不存在返回false
     */
    //@ConditionalOnBean(Apple.class)
     /*
        判断当前环境中是否有Apple Bean,如果有返回false, 不存在返回true
     */
    //@ConditionalOnMissingBean(Apple.class)
    /*
        判断当前环境中的配置文件中是否存在对应的key 和val
     */
    //@ConditionalOnProperty(name = "itheima", havingValue = "33")
    /*
    application.properties 中读取
判断当前环境中是否存在 Apple类,如果存在则返回true, 否则false */ @ConditionalOnClass(Apple.class) public User user(){ User user = new User(); user.setName("武大郎"); user.setAge(1); return user; } }

 以上注解用于自动配置或特殊场景下是否记载某个或注入某个Spring组件

自动配置详细过程

在springboot源码中 详情转到 https://www.cnblogs.com/theRhyme/p/11057233.html#_lab2_3_2

在源码中加载时 AutoConfigurationImportSelector 类中有一个 方法 

 此方法加载了一个文件

 此文件中的数据时所有自动配置类的全限定类名,截取一部分

在这个配置文件中声明了需要实现自动配置的类,并且全限定类名,接下来通过反射去创建初始化这些类,那么这些类里面一般添加了@Conditional相关注解,并且注解中的判断条件一般是当前环境中是否导入了相对应的依赖,如果存在则会启用自动配置。

 我们这里还是以redis举例

 第一个红框解释,判断是否有此依赖,有则加载配置。

第二个解释,查看用户是否自动注入了配置,有则使用用户的。

原文地址:https://www.cnblogs.com/xiaozhang666/p/13823221.html