• 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举例

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

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

  • 相关阅读:
    POJ 1860 Currency Exchange (Bellman ford)
    POJ 1502 MPI Maelstrom (最短路)
    2015 Multi-University Training Contest 2 1006(DFS)
    HDU 1495 非常可乐(枚举+DFS)
    HDU 5289 Assignment(单调队列)
    ACDream 1734 Can you make a water problem?(贪心)
    ACDream 1735 输油管道
    ACDream 1726 A Math game (折半查找)
    CSU 1602 Needle Throwing Game (投针问题)
    CSU 1604 SunnyPig (BFS)
  • 原文地址:https://www.cnblogs.com/xiaozhang666/p/13823221.html
Copyright © 2020-2023  润新知