springBoot配置环境动态切换

建立第一个配置文件(springBoot默认读取的文件)application.properties

test.name=default
test.defaultAge=12

建立第二个配置文件(开发环境)application-dev.properties

test.name=dev
test.devAge=13

建立第三个配置文件(用户验收测试环境)application-uat.properties

test.name=uat
test.uatAge=14

1.添加启动参数(--spring.profiles.active=),测试结果读取application.properties的值
2.添加启动参数(--spring.profiles.active=dev),测试结果读取application-dev.properties的值
3.添加启动参数(--spring.profiles.active=uat),测试结果读取application-uat.properties的值
4.添加启动参数(--spring.profiles.active=uat,dev),测试结果读取application-dev.properties的值
5.添加启动参数(--spring.profiles.active=dev,uat),测试结果读取application-uat.properties的值
6.添加启动参数(--spring.profiles.active=dev),可以读到application.properties的(test.defaultAge)值,读不到uat的(test.uatAge)值。
7.添加启动参数(--spring.profiles.active=uat),可以读到application.properties的(test.defaultAge)值,读不到dev的(test.devAge)值。
8.添加启动参数(--spring.profiles.active=),可以读到application.properties的值,读取不到其他配置文件的值

重点

  • 添加启动参数--spring.profiles.active=“环境代表参数”(此值为文件名“-”与“.”中间的值,此处即为dev或者uat)
  • 可以添加多个参数,通过英文逗号(,)分割
  • 如果添加多个参数,有重复key,值会被覆盖,(配置文件加载顺序详见官方文档:24. Externalized Configuration)
  • 也可以直接在application.properties配置文件中添加spring.profiles.active=“环境代表参数” 来替代启动时候添加的参数

springBoot自动配置bean(@Conditional注解使用)

首先看一个正常配置的bean与打印

建立一个接口

package com.yxj.spring;/*** @ProjectName: springBootDemo* @Package: com.yxj.spring* @Description:* @Author:     阿杰* @CreateDate: 2019/1/22 22:08* @UpdateUser: 暂无* @UpdateDate: 2019/1/22 22:08* @UpdateRemark: The modified content* @Version: 1.0*/
public interface MakeApp {
}

建立两个实现-第一个

package com.yxj.spring;/*** @ProjectName: springBootDemo* @Package: com.yxj.spring* @Description:* @Author: 阿杰* @CreateDate: 2019/1/22 22:13* @UpdateUser: 暂无* @UpdateDate: 2019/1/22 22:13* @UpdateRemark: The modified content* @Version: 1.0*/
public class Wechat implements MakeApp {
}

建立两个实现-第二个

package com.yxj.spring;/*** @ProjectName: springBootDemo* @Package: com.yxj.spring* @Description:* @Author: 阿杰* @CreateDate: 2019/1/22 22:14* @UpdateUser: 暂无* @UpdateDate: 2019/1/22 22:14* @UpdateRemark: The modified content* @Version: 1.0*/
public class PipiXia implements MakeApp {
}

通过@SpringBootConfiguration与@Bean加载bean

package com.yxj.spring;import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;/*** @ProjectName: springBootDemo* @Package: com.yxj.spring* @Description:  @SpringBootConfiguration继承自@Configuration,* 二者功能也一致,标注当前类是配置类,* 并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到spring容器中,* 并且实例名就是方法名。* @Author: 阿杰* @CreateDate: 2019/1/22 22:14* @UpdateUser: 暂无* @UpdateDate: 2019/1/22 22:14* @UpdateRemark: The modified content* @Version: 1.0*/
@SpringBootConfiguration
public class LoadMyBean {@Beanpublic MakeApp createWechat(){return new Wechat();}@Beanpublic MakeApp createPipiXia(){return new PipiXia();}
}

springBoot启动类测试

package com.yxj.spring;import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;import java.util.List;/*** @ProjectName: springBootDemo* @Package: com.yxj.spring* @Description:* @Author: 杨小杰* @CreateDate: 2019/1/18 20:18* @UpdateUser: 暂无* @UpdateDate: 2019/1/18 20:18* @UpdateRemark: The modified content* @Version: 1.0*/
@SpringBootApplication
public class SpringBootTestRun {/*** getBeansOfType(MakeApp.class)会装配bean类型是MakeApp的所有实例* @param args*/public static void main(String[] args) {ConfigurableApplicationContext run = SpringApplication.run(SpringBootTestRun.class, args);System.out.println("------------------分割线------------------");System.out.println(run.getBeansOfType(MakeApp.class));}
}

测试结果

------------------分割线------------------
{createWechat=com.yxj.spring.Wechat@5cad8b7d, createPipiXia=com.yxj.spring.PipiXia@7b02e036}

可以看到结果把通过@Bean加载的两个MakeApp实现类对象全部打印出来了

了解Condition接口,实现自定义bean的加载

源代码

/** Copyright 2002-2017 the original author or authors.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**      http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package org.springframework.context.annotation;import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.core.type.AnnotatedTypeMetadata;/*** A single {@code condition} that must be {@linkplain #matches matched} in order* for a component to be registered.** <p>Conditions are checked immediately before the bean-definition is due to be* registered and are free to veto registration based on any criteria that can* be determined at that point.** <p>Conditions must follow the same restrictions as {@link BeanFactoryPostProcessor}* and take care to never interact with bean instances. For more fine-grained control* of conditions that interact with {@code @Configuration} beans consider the* {@link ConfigurationCondition} interface.** @author Phillip Webb* @since 4.0* @see ConfigurationCondition* @see Conditional* @see ConditionContext*/
@FunctionalInterface
public interface Condition {/*** Determine if the condition matches.* @param context the condition context* @param metadata metadata of the {@link org.springframework.core.type.AnnotationMetadata class}* or {@link org.springframework.core.type.MethodMetadata method} being checked* @return {@code true} if the condition matches and the component can be registered,* or {@code false} to veto the annotated component's registration*/boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);}

上诉代码描述了matches返回值如果是ture就会再加bean,反之则反

实现自定义Condition

新建Wechat自定义Condition,默认返回false(不装配bean)

package com.yxj.spring;import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.util.StringUtils;/*** @ProjectName: springBootDemo* @Package: com.yxj.spring* @Description:* @Author: 阿杰* @CreateDate: 2019/1/22 22:35* @UpdateUser: 暂无* @UpdateDate: 2019/1/22 22:35* @UpdateRemark: The modified content* @Version: 1.0*/
public class WechatCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {return false;}
}

新建PipiXia自定义Condition,默认返回true(装配bean)

package com.yxj.spring;import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.util.StringUtils;/*** @ProjectName: springBootDemo* @Package: com.yxj.spring* @Description:* @Author: 阿杰* @CreateDate: 2019/1/22 22:35* @UpdateUser: 暂无* @UpdateDate: 2019/1/22 22:35* @UpdateRemark: The modified content* @Version: 1.0*/
public class PipiXiaCondition implements Condition {/***当name不为空的时候,判断如果name中包含appName的时候返回true* @param context* @param metadata* @return*/@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {return true;}
}

在@Bean所在的类中添加自定义条件,配合@Conditional注解来实现

package com.yxj.spring;import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;/*** @ProjectName: springBootDemo* @Package: com.yxj.spring* @Description:  @SpringBootConfiguration继承自@Configuration,* 二者功能也一致,标注当前类是配置类,* 并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到spring容器中,* 并且实例名就是方法名。* @Author: 阿杰* @CreateDate: 2019/1/22 22:14* @UpdateUser: 暂无* @UpdateDate: 2019/1/22 22:14* @UpdateRemark: The modified content* @Version: 1.0*/
@SpringBootConfiguration
public class LoadMyBean {@Bean@Conditional(WechatCondition.class)public MakeApp createWechat(){return new Wechat();}@Bean@Conditional(PipiXiaCondition.class)public MakeApp createPipiXia(){return new PipiXia();}
}

再次测试,测试结果

------------------分割线------------------
{createPipiXia=com.yxj.spring.PipiXia@420bc288}

可以看到只打印了一个pipixia实例bean,微信没有装配进来

SpringBoot中自带的Condition实现


可以看到这个是继承了@Conditional注解,传了自定义的class对象,变成了一个新的注解
常用@Conditional注解使用,可以查看大佬博客https://blog.csdn.net/u012437781/article/details/78626617

@Import注解

用处

  • @Import其实就是引入一个或多个配置,可以导入普通类,也可以导入配置类(上述的LoadMyBean为配置类,主要通过@Bean生成bean给spring管理)
  • @Import用来导入一个或多个类(会被spring容器管理),或者配置类(配置类里的@Bean标记的类也会被spring容器管理)

测试

还是以上的例子,去掉配置类(LoadMyBean)中的@SpringBootConfiguration注解

package com.yxj.spring;import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;/*** @ProjectName: springBootDemo* @Package: com.yxj.spring* @Description:  @SpringBootConfiguration继承自@Configuration,* 二者功能也一致,标注当前类是配置类,* 并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到spring容器中,* 并且实例名就是方法名。* @Author: 阿杰* @CreateDate: 2019/1/22 22:14* @UpdateUser: 暂无* @UpdateDate: 2019/1/22 22:14* @UpdateRemark: The modified content* @Version: 1.0*/
public class LoadMyBean {@Bean@Conditional(WechatCondition.class)public MakeApp createWechat(){return new Wechat();}@Bean@Conditional(PipiXiaCondition.class)public MakeApp createPipiXia(){return new PipiXia();}
}

修改springboot启动类,添加@Import注解

package com.yxj.spring;import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.*;import java.util.List;/*** @ProjectName: springBootDemo* @Package: com.yxj.spring* @Description:* @Author: 杨小杰* @CreateDate: 2019/1/18 20:18* @UpdateUser: 暂无* @UpdateDate: 2019/1/18 20:18* @UpdateRemark: The modified content* @Version: 1.0*/
@SpringBootApplication
@Import(LoadMyBean.class)
public class SpringBootTestRun {/*** getBeansOfType(MakeApp.class)会装配bean类型是MakeApp的所有实例* @param args*/public static void main(String[] args) {ConfigurableApplicationContext run = SpringApplication.run(SpringBootTestRun.class, args);System.out.println("------------------分割线------------------");System.out.println(run.getBeansOfType(MakeApp.class));}
}

测试结果

------------------分割线------------------
{createPipiXia=com.yxj.spring.PipiXia@6548bb7d}

测试结果表明了,虽然配置类没有加入@SpringBootConfiguration,@Component,@Service,@Controller等交给spring管理的注解,但是通过启动类添加@Import引入方式,仍然可以在spring进行依赖注入,交由spring管理

声明

  • 本人是与springBoot教学视频同步学习,此文章是看视频与查阅各位大佬博客文章总结出来的重点内容。
  • 如果觉得文章描绘的不够清楚,欢迎留言,也可以关注公众号,在公众号内发送关键字“springboot”或者“springBoot”领取springBoot教程。
    排版不易,希望大家能够点点关注,共同学习,有问题请指出,谢谢大家。
  • ps:我也希望本人能够精准表达springBoot的一些重点内容,减少大家观看视频的大额时间。

springBoot学习(二)配置环境动态切换和部分注解的运用相关推荐

  1. Spring多数据源配置以及动态切换实现

    Spring多数据源配置以及动态切换实现 问题描述 一:首先是配置数据源 1.使用xml的bean节点来配置 2.使用yml配置+java代码实现配置 二:动态数据源 三:使用AOP切面实现动态数据源 ...

  2. SpringBoot+AOP实现多数据源动态切换

    SpringBoot+AOP实现多数据源动态切换 背景 设计总体思路 步骤 背景 系统后端需要访问多个数据库,现有的数据库连接配置写入配置文件中.后端需要从一个数据库的配置表里动态的读取其它mysql ...

  3. springboot使用mybatis多数据源动态切换的实现

    需求:项目使用了读写分离,或者数据进行了分库处理,我们希望在操作不同的数据库的时候,我们的程序能够动态的切换到相应的数据库,执行相关的操作. 首先,你需要一个能够正常运行的springboot项目,配 ...

  4. Spring-Boot + AOP实现多数据源动态切换

    2019独角兽企业重金招聘Python工程师标准>>> 最近在做保证金余额查询优化,在项目启动时候需要把余额全量加载到本地缓存,因为需要全量查询所有骑手的保证金余额,为了不影响主数据 ...

  5. Centos7云服务器部署SpringBoot项目(手动配置环境篇)

    文章目录 前言 一.部署Tomcat服务器 1.安装JDK1.8 2.安装与启动tomcat 配置安全组(8080端口) 二.安装JDK8 三.Mysql5.7安装 1.下载mysql 2.启动MyS ...

  6. SpringBoot 学习二:操作数据库

    2019独角兽企业重金招聘Python工程师标准>>> 本文将从以下几个方面介绍: 前言 配置数据源 SpringBoot 整合 Mybatis SpringBoot 整合 Jdbc ...

  7. (转)全文检索技术学习(二)——配置Lucene的开发环境

    http://blog.csdn.net/yerenyuan_pku/article/details/72589380 Lucene下载 Lucene是开发全文检索功能的工具包,可从官方网站http: ...

  8. Xamarin 学习笔记 - 配置环境(Windows iOS)

    2019独角兽企业重金招聘Python工程师标准>>> 本文翻译自CodeProject文章:https://www.codeproject.com/Articles/1223980 ...

  9. 2.SpringBoot学习(二)——Spring Boot ConfigurationProperties

    1.简介 1.1 概述 Annotation for externalized configuration. Add this to a class definition or a @Bean met ...

最新文章

  1. asp.net mvc 重定向
  2. 【FPGA VerilogHDL】第一次尝试:LED灯基础实验
  3. Python爬取网页
  4. 二维数组按行和按列遍历的效率
  5. Possible iteration over unexpected (custom / inherited) members, probably missing hasOwnProperty che
  6. 在网页设计中,引导页是所有页面中的重中之重,引导浏览者很快进入各栏目页面,是一个网站的灵魂所在。
  7. java文件编译为class文件需要键入什么命令_Day02:Java语言基础-第一个Java程序以及编译与运行机制...
  8. Windows2000系统下Apache2和PHP4安装终级宝典
  9. Github上关于iOS的各种开源项目集合(强烈建议大家收藏,查看,总有一款你需要)
  10. 计算机硬盘大小一般都是整数,完美主义 最精确的硬盘整数分区法
  11. ( 教程 ) 微信公众号做淘宝优惠券自动查券返利机器人怎么设置?
  12. Compile fails with 3.5 framework but succeeds with 4.0
  13. android intent传文件,android如何用intent跳转到文件管理器
  14. 小白白之青龙面板搭建
  15. Poading Analysis
  16. 撒罗满:2019年收集的最佳3D打印模型下载网站
  17. 使用fiddler获取ios手机接口
  18. 工程流体力学笔记暂记3(流体运动的基本概念:流动的分类,迹线和流线+流线的计算例题)
  19. 双重差分 difference-in-differences
  20. 攻防世界PWN之cnss题解

热门文章

  1. 软件测试/测试开发丨必知必会的Docker 命令
  2. [转]PROE传动链条的装配教程
  3. 基于微信小程序食谱大全系统(微信小程序毕业设计)
  4. unirech:阿里云国际站云服务器和国内站产品有什么区别?
  5. 基于Mind+、MOTT实现人工智能
  6. 对话三星张代君:Bixby到底与Siri有什么不同? | AI英雄
  7. 如何在手机上查询快递?
  8. 做好工作交接对自己多重要,说到心坎了
  9. java:去除数组重复元素的四种方法
  10. 虚拟化1-创建虚拟机