Java高级开发

Springboot_全局配置、自动配置、条件注解

2019-06-20  本文已影响1人  程序员夏天

1. 全局配置文件 

 SpringBoot项目使用一个全局配置文件application.properties或者是application.yml来进行全局配置。

     配置位置:一般来讲,配置文件一般放在resource目录下或者类路径下的/config下。通常我们都是放在resource下。

我们来看下@SpringBootApplication注解的源码

spring:

    profiles:

        # 使用那个配置

        active: prod   

    datasource:

        name: dataSource

        username: XXX

        password: XXX

        # 使用druid数据源

        type: com.alibaba.druid.pool.DruidDataSource

        driver-class-name: com.mysql.jdbc.Driver

#        filters: stat

#        maxActive: 20

#        initialSize: 1

#        maxWait: 60000

#        minIdle: 1

#        timeBetweenEvictionRunsMillis: 60000

#        minEvictableIdleTimeMillis: 300000

#        validationQuery: select 'x'

#        testWhileIdle: true

#        testOnBorrow: false

#        testOnReturn: false

#        poolPreparedStatements: true

#        maxOpenPreparedStatements: 20

#        removeAbandoned: false

logging:

  config: classpath:logbak.xml

#server:

#  ssl:

#    key-store: classpath:vc.dahancloud.com.jks

#    key-store-password: 4zc8zi119d2

---

# 开发环境配置

spring:

  profiles: dev

  datasource:

    url: jdbc:mysql://localhost:3306/iot?useUnicode=true&characterEncoding=UTF-8

server:

  port: 8080

---

# 测试环境配置

spring:

  profiles: prod

  datasource:

    url: jdbc:mysql://x.x.x.x:3306/iot?useUnicode=true&characterEncoding=UTF-8

server:

  port: 9097

alarmservice:

  alarm: http://localhost:8093

说明:springboot的全局配置文件除了以上这些还有很多,可以参考一下API文档。

2. starter pom 

SpringBoot为我们提供了简化企业开发绝大多数场景的starter pom,只要使用了应用场景所需要的starter pom,相关的技术配置就会消除,就可以得到SpringBoot为我们提供的自动配置Bean。

 官方文档上提供的start pom有以下:

以上是列举一些starter pom ,还有一些并没有列举出来。如果需要可以自己去查阅文档。并且一些第三方技术都有自己推出的starter pom

3. 自动配置分析 

我们可以通过maven的命令dependency:sources来下载该maven项目中的所有依赖包的源码。

我们在使用SpringBoot的时候会先生成一个SpringApplicaiton类,于是我们来分析一下这个类在生成中是如何进行自动配置的:/font>

//SpringApplicaiotn类的初始化方法

@SuppressWarnings({"unchecked","rawtypes"})

private void initialize (Object[] sources){

    if(sources!=null && sources.length>0){

        this.sources.addAll(Arrays.asList(source));

    }

    this.webEnvironment = deduceWebEnvironment();

    //注意这一步,这一步是进行自动配置

    setInitializers((Collection)getSpringFactoriesInstances(

            ApplictionContextInitializer.class));

    setListeners((Collection)getSpringFactoriesInstances(

            ApplicaitonListener.class));

    this.mainApplicationClass = deduMainApplicationClass();

}

接着我们来看一下getSpringFactoriesInstance方法的源码

private <T> Collection<? extends T>getSpringFactoriesInstance(Class<T> type){

    return getSpringFactoriesInstance(type, new Class<?>[]{});

}

//我们来看下getSpringFactoriesInstance这个方法源码

private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type,

            Class<?>[] paramterTypes, Object... args){

    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

    //使用names确保唯一性,防止重复

    Set<String> names = new LinkedHashSet<String>(

                //类加载器

                SpringFactoriesLoader.loadFactoryNames(type,classLoader));

    List<T> instances = createrSpringFactoriesInstances(type,parameterTypes,

                        classLoader,args,names);

    AnnotationAwareOrderComparator.sort(instances);

    return instances;

}

我们来看下通过loadFactoryNames方法加载的情况

//配置的路径

public static final String FACTORIES_RESOURCE_LOCATION =

                                    "META-INF/spring.factories";

public static List<String> loadFactoryNames(Class<?> factoryClass,

                ClassLoader classLoder){

    String factoryName = factoryClass.getName();

    try{

        Enumeration<URL> urls =(ClassLoader!=null ?

                    ClassLoader.getResource(FACTORIES_RESOURCE_LOCATION)) :

                    ClassLoader.getSystemResource(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(Array.asList(

              StringUtils.commaDelimitedListToStringArray(factoryClassNames)));

        }

        return result;

    }catch(IOException ex){

        throw new IllegalArgumentException("Unable to load ["

                + factoryClass.getName)+"] factories from location ["

                + FACTORIES_RESOURCE_LOCATION + "]",ex);

    }

}

SpringBoo在进行SpringApplication对象实例化时会加载META-INF/spring.factories将其转变成对象,将该配置文件中的配置载入到Spring容器中。而这个配置文件里面配置了很多内容。

4. 条件注解 

 我们在翻阅自动配置的过程中,可以回遇见很多条件注解,这边把常见的条件注解列举一下:

                                                                                           喜欢的话可以转发下朋友圈,谢谢支持

上一篇下一篇

猜你喜欢

热点阅读