zoukankan      html  css  js  c++  java
  • springBoot 自动配置原理

      在之前文章中说过,springBoot会根据jar包去添加许多的自动配置,本文就来说说为什么会自动配置,自动配置的原理时什么?

      springBoot在运行SpringApplication对象实例化时,就会去加载 META-INF/spring.factories文件,就会将这个文件中的配置都加载到spring容器中。下面,我们去看看SpringApplication对象的初始化方法 initialize() 方法。

      因为我们在项目启动时有用到这个对象,所以,我们可以直接从这里进入。

      找到 initialize()方法,发现,在其中存在一个获取初始化参数的方法。

      我们继续向下跟进。

      继续跟进,我发现里面存在两个方法,第一个获取配置中的类的名字,第二个将配置中的类创建为一个个对象。

      接下来,我先跟进SpringFactoriesLoader.loadFactoryNames()方法。(笔记本屏幕显示不下,所以直接拉代码过来,就不截图了)

    public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
            String factoryClassName = factoryClass.getName();
            try {
                Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
                        ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
                List<String> result = new ArrayList<String>();
                while (urls.hasMoreElements()) {
                    URL url = urls.nextElement();
                    Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
                    String factoryClassNames = properties.getProperty(factoryClassName);
                    result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
                }
                return result;
            }
            catch (IOException ex) {
                throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() +
                        "] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex);
            }
        }

       我发现上面使用到一个常量 FACTORIES_RESOURCE_LOCATION ,去找到这个常量。

     

      这个常量存放了一个文件位置,而这个文件中存放的就是自动配置的一个个对象。去找到它们。

      找到这些对象之后,继续执行createSpringFactoriesInstances()方法。将上面获取到的对象名称全部实例化为一个个对象。

     

      在spring-boot-autoconfigure的包下,也同样有一个spring.factories文件,上面的文件中主要包含的是一些系统级的自动配置,而在spring-boot-autoconfigure包下的则是一些第三方的自动配置,比如下面的redis等等。

     

      我们进入到redis去看看,我发现在其头部有一句注解@ConditionalOnClass,这个注解的意思是,只有系统中有这几个类时,才会去加载配置这个类,如果没有则不去加载配置。

     

      在下面这个对象中,自动去加载redis的配置

      而这些配置参数则时去 application.properties文件中去找的,这个文件中的基础配置在我之前的文章中有写过(springBoot application.properties 基础配置)。

     

      以上就是springBoot的自动化配置的原理,当然,我们知道了这些原理,其实就可以模仿这种方式在项目中加入自定义的自动化配置。

      最后附上一些条件注解,在上面的自动化配置中也经常使用到。

    注解解释
    @ConditionalOnBean 当容器中有指定Bean的条件下
    @ConditionalOnClass 当路径下有指定类的条件下
    @ConditionalOnExpression 基于SqEL表达式作为判断条件
    @ConditionalOnJava 基于JVM版本作为判断条件
    @ConditionalOnJndi 在JNDI存在的条件下查找指定位置
    @ConditionalOnMissingBean 当容器中没有指定Bean的情况下
    @ConditionalOnMissingClass 当类路径下没有指定的类的条件下
    @ConditionalOnNotWebApplication 当前项目不是Web项目的情况下
    @ConditionalOnProperty 指定的属性是否有指定的值
    @ConditionalOnResource 类路径是否有指定的值
    @ConditionalOnSingleCandidate 当前指定Bean在容器中只有一个,或者虽然有多个但是指定首选的Bean
    @ConditionalOnWebApplication 当前项目时Web项目的条件下

    -------------------- END ---------------------

    
    

    最后附上作者的微信公众号地址和博客地址 

    
    

    公众号:wuyouxin_gzh

    
    

    
    

     

    
    

    Herrt灬凌夜:https://www.cnblogs.com/wuyx/

     

  • 相关阅读:
    JDOJ 1090: 矩阵
    JDOJ 2236: Random Num
    浅谈区间DP
    NOIP 2006 能量项链
    小技巧—处理环形区间
    NOI 1995 石子合并
    洛谷 P5640 【CSGRound2】逐梦者的初心
    JDOJ 1101: 邦德I
    JDOJ 1104: 最佳挑水
    JDOJ 1098: 夏娜的菠萝包
  • 原文地址:https://www.cnblogs.com/wuyx/p/9744511.html
Copyright © 2011-2022 走看看