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

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有以下:

名称描述
spring-boot-startSpringBoot核心start,包含自动配置、日志、yml配置文件的支持
spring-boot-start-actuator准生产特性,用来监控和管理应用
spring-boot-start-remote-shell提供基于SSH协议的监控和管理
spring-boot-starter-amqp使用spring-rabbit来支持AMQP
spring-boot-start-aop使用spring-aop和AspectJ支持面向切面编程
spring-boot-starter-batch对Spring Batch支持
spring-boot-starter-cloud-connectors对云平台(Cloud Foundy、Heroku)提供的服务提供简化的连接方式
spring-boot-starter-data-elasticsearch通过spring-data-elasticsearch对Elasticsearch支持
spring-boot-starter-data-gemfire通过spring-data-gemfire对分布式存储GemFile的支持
spring-boot-starter-data-jpa对JPA的支持,包含spring-data-jpa、spring-orm和Hibernate
spring-boot-starter-jdbc对JDBC数据库的支持
spring-boot-starter-mail对javax.mail的支持
spring-boot-starter-redis对键值对内存数据库Redis的支持,包含spring-redis
spring-boot-starter-security对spring-security的支持
spring-boot-starter-social-facebook通过spring-social-facebook对Facebook的支持
spring-boot-starter-web对web项目开发的支持,包含Tomcat和spring-webmvc
spring-boot-starter-TomcatSpringBoot默认的Servlet容器Tomcat
spring-boot-starter-loggingSping Boot 默认的日志框架Logback
spring-boot-starter-log4j支持使用Log4J日志框架
spring-boot-starter-websocket对WebSocket开发的支持
spring-boot-starter-ws对Spring Web Services的支持


以上是列举一些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. 条件注解
 我们在翻阅自动配置的过程中,可以回遇见很多条件注解,这边把常见的条件注解列举一下:

注解解释
@ConditionalOnClass({xxx.class})当存在xxx类的情况下,才会实例化该类
@ConditionalOnBean当容器里有指定的Bean的情况下
@ConditionalOnExpression基于SpEL表达式作为判断条件
@ConditionalOnJava基于JVM版本作为判断条件
@ConditionalOnJndi在JNDI存在的条件下查找指定的位置
@ConditionalOnMissingBean当容器里没有指定Bean的情况下
@ConditionalOnMissingClass当容器里没有指定类的条件下
@ConditionalOnNotWebApplication当前项目不是web项目的情况下
@ConditionalOnProperty指定属性是否有指定的值
@ConditionalOnResource类路径是否有指定的值
@ConditionalOnSingleCandidate指定Bean在容器中只有一个,
或者虽然有多个但是指定首选的Bean
@ConditionalOnWebApplicaiton当前项目时Web项目的条件下
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值