springBoot学习(二)配置环境动态切换和部分注解的运用
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学习(二)配置环境动态切换和部分注解的运用相关推荐
- Spring多数据源配置以及动态切换实现
Spring多数据源配置以及动态切换实现 问题描述 一:首先是配置数据源 1.使用xml的bean节点来配置 2.使用yml配置+java代码实现配置 二:动态数据源 三:使用AOP切面实现动态数据源 ...
- SpringBoot+AOP实现多数据源动态切换
SpringBoot+AOP实现多数据源动态切换 背景 设计总体思路 步骤 背景 系统后端需要访问多个数据库,现有的数据库连接配置写入配置文件中.后端需要从一个数据库的配置表里动态的读取其它mysql ...
- springboot使用mybatis多数据源动态切换的实现
需求:项目使用了读写分离,或者数据进行了分库处理,我们希望在操作不同的数据库的时候,我们的程序能够动态的切换到相应的数据库,执行相关的操作. 首先,你需要一个能够正常运行的springboot项目,配 ...
- Spring-Boot + AOP实现多数据源动态切换
2019独角兽企业重金招聘Python工程师标准>>> 最近在做保证金余额查询优化,在项目启动时候需要把余额全量加载到本地缓存,因为需要全量查询所有骑手的保证金余额,为了不影响主数据 ...
- Centos7云服务器部署SpringBoot项目(手动配置环境篇)
文章目录 前言 一.部署Tomcat服务器 1.安装JDK1.8 2.安装与启动tomcat 配置安全组(8080端口) 二.安装JDK8 三.Mysql5.7安装 1.下载mysql 2.启动MyS ...
- SpringBoot 学习二:操作数据库
2019独角兽企业重金招聘Python工程师标准>>> 本文将从以下几个方面介绍: 前言 配置数据源 SpringBoot 整合 Mybatis SpringBoot 整合 Jdbc ...
- (转)全文检索技术学习(二)——配置Lucene的开发环境
http://blog.csdn.net/yerenyuan_pku/article/details/72589380 Lucene下载 Lucene是开发全文检索功能的工具包,可从官方网站http: ...
- Xamarin 学习笔记 - 配置环境(Windows iOS)
2019独角兽企业重金招聘Python工程师标准>>> 本文翻译自CodeProject文章:https://www.codeproject.com/Articles/1223980 ...
- 2.SpringBoot学习(二)——Spring Boot ConfigurationProperties
1.简介 1.1 概述 Annotation for externalized configuration. Add this to a class definition or a @Bean met ...
最新文章
- asp.net mvc 重定向
- 【FPGA VerilogHDL】第一次尝试:LED灯基础实验
- Python爬取网页
- 二维数组按行和按列遍历的效率
- Possible iteration over unexpected (custom / inherited) members, probably missing hasOwnProperty che
- 在网页设计中,引导页是所有页面中的重中之重,引导浏览者很快进入各栏目页面,是一个网站的灵魂所在。
- java文件编译为class文件需要键入什么命令_Day02:Java语言基础-第一个Java程序以及编译与运行机制...
- Windows2000系统下Apache2和PHP4安装终级宝典
- Github上关于iOS的各种开源项目集合(强烈建议大家收藏,查看,总有一款你需要)
- 计算机硬盘大小一般都是整数,完美主义 最精确的硬盘整数分区法
- ( 教程 ) 微信公众号做淘宝优惠券自动查券返利机器人怎么设置?
- Compile fails with 3.5 framework but succeeds with 4.0
- android intent传文件,android如何用intent跳转到文件管理器
- 小白白之青龙面板搭建
- Poading Analysis
- 撒罗满:2019年收集的最佳3D打印模型下载网站
- 使用fiddler获取ios手机接口
- 工程流体力学笔记暂记3(流体运动的基本概念:流动的分类,迹线和流线+流线的计算例题)
- 双重差分 difference-in-differences
- 攻防世界PWN之cnss题解