最近在读spring实战一书,个人感觉内容通俗易懂,学到了一些之前并不知道的知识,于是打算在博客里记录一下这些知识点便于后期记忆;

  今天要记录的就是spring的条件化创建bean,针对条件化创建bean方面spring有两方面处理机制,分别是spring3.1引入的profile机制和4.0引入的通过@Conditional注解来定义条件化的bean,下面进行一一介绍.其中例子全部copy书中的案例

  一、profile机制

  书中是通过要创建三个分别适用于开发,生产和qa环境的DataSource来引出条件化bean的 需求并通过profile机制解决的,这里只记录开发、生产两个环境,引入profile之前,我们创建开发和生产的DataSource关键代码如下:

/*
* 适用于开发环境的DataSource
*/
@Bean
public DataSource dataSource(){
return new EmbeddedDatabaseBuilder()
.addScript("classpath:schema.sql")
.addScript("classpath:test-data.sql")
.build();
} /*
* 适用于生产环境的DataSource
*/
@Bean
public DataSource dataSource(){
JndiObjectFactoryBean bean = new JndiObjectFactoryBean ();
bean.setJndiName('');
bean.setResourceRef(true);
bean.setProxyInterfence(java.sql.DataSource.class);
return (DataSource ) bean.getObject();
}

如果是这样的话每次发布和开发的时候需要更改代码会显得麻烦,所以就需要引入一个机制来让spring知道根据环境的不同来创建合适的bean,下面就需要开始使用profile来完成这一功能.

首先看下基于java的配置中该如何引入profile

在Java配置中,可以使用@Profile注解指定某个bean属于哪一个profile.详见代码:

需要注意的是以上代码的@Profile注解直接用在了方法上,这在spring3.2之前是不允许的,3.2之前只允许作用在类上,这难免会造成代码的冗余,因为每个bean都要给它单独定义一个类来装配profile;

然后了解一下基于xml配置如何引入profile,直接上代码:

这样无论是基于java还是xml,都已成功引入profile,那么我们如何激活profile从而让spring知道到底要创建哪个bean呢

Spring在确定哪个profile处于激活状态时,需要依赖两个独立的属性:spring.profiles.active和spring.profiles.default。
如果设置了spring.profiles.active属性的话,那么它的值就会用来确定哪个profile是激活的。但如果没有设置spring.profiles.active
属性的话,那Spring将会查找spring.profiles.default的值。如果spring.profiles.active和spring.profiles.default
均没有设置的话,那就没有激活的profile,因此只会创建那些没有定义在profile中的bean。

有多种方式来设置这两个属性:
作为DispatcherServlet的初始化参数;
作为Web应用的上下文参数;
作为JNDI条目;
作为环境变量;
作为JVM的系统属性;
在集成测试类上,使用@ActiveProfiles注解设置。

下面贴上书中激活profile的代码:

使用profile进行测试

当运行集成测试时,通常会希望采用与生产环境(或者是生产环境的部分子集)相同的配置进行测试。但是,如果配置中的bean定义在了profile中,那么在运行测试时,我们就需要有一种方式来启用合适的profile。
Spring提供了@ActiveProfiles注解,我们可以使用它来指定运行测试时要激活哪个profile。在集成测试时,通常想要激活的是开发环境的profile。例如,下面的测试类片段展现了使用@ActiveProfiles激活dev profile:

至此spring通过profile来实现条件化创建bean就记录完了,下篇记录如何通过Spring 4.0中提供的@Conditional注解来更高级的条件化创建bean

spring对bean的高级装配之profile机制的更多相关文章

  1. spring对bean的高级装配之基于@Conditional条件化装配

    上篇介绍了如何基于profile来条件化创建bean,spring会根据profile的激活状态来进行创建;这篇介绍如何基于spring4.0引入的@Conditional和Condition接口来更 ...

  2. Spring高级装配(一) profile

    Spring高级装配要学习的内容包括: Spring profile 条件化的bean声明 自动装配与歧义性 bean的作用域 Spring表达式语言 以上属于高级一点的bean装配技术,如果你没有啥 ...

  3. 第3章—高级装配—配置profile bean

    配置profile bean 3.1.@profile注解是spring提供的一个用来标明当前运行环境的注解. 我们正常开发的过程中经常遇到的问题是,开发环境是一套环境,qa测试是一套环境,线上部署又 ...

  4. Spring 梳理-bean配置与装配

    1       bean配置与装配 1.1      bean在XML文件中进行显示配置并装配 1.2      bean在JavaConfig中显示配置并装配 1.2.1  优点:类型是安全的,编译 ...

  5. Spring学习总结之高级装配

    1.  profile profile可以决定bean在什么环境下才被装配(开发环境.测试环境.线上环境等) @Profile(“dev”)可以用在class之前,也可以用在类之前(Spring3.2 ...

  6. spring中bean的高级属性之list, set, map以及props元素(含举例)

    转自:http://qingfeng825.iteye.com/blog/144704 list, set, map和props元素分别用来设置类型为List,Set,Map和Propertis的属性 ...

  7. 【Spring】高级装配

    前言 前面讲解了bean的核心装配技术,其可应付很多中装配情况,但Spring提供了高级装配技术,以此实现更为高级的bean装配功能. 高级装配 配置profile bean 将所有不同bean定义放 ...

  8. 简:Spring中Bean的生命周期及代码示例

    (重要:spring bean的生命周期. spring的bean周期,装配.看过spring 源码吗?(把容器启动过程说了一遍,xml解析,bean装载,bean缓存等)) 完整的生命周期概述(牢记 ...

  9. Spring实战(四)Spring高级装配中的bean profile

    profile的原意为轮廓.剖面等,软件开发中可以译为“配置”. 在3.1版本中,Spring引入了bean profile的功能.要使用profile,首先要将所有不同的bean定义整理到一个或多个 ...

随机推荐

  1. K-wolf Number (数位DP)

    题意:求区间内有多少个数满足条件:任意相邻的k个数位都不相等. 思路:老套路 #include<bits/stdc++.h> using namespace std; typedef lo ...

  2. QT https 程序运行异常

    [1]问题现象描述 利用QT的https方式访问服务器,添加了libeay32.dll 和 ssleay32.dll, 且一直都使用正常. 正常现象:返回200,且该获取的值都正常返回(即replyB ...

  3. 洛谷P2820 局域网 (最小生成树)

    题目链接:https://www.luogu.org/problemnew/show/P2820 题目背景 某个局域网内有n(n<=100)台计算机,由于搭建局域网时工作人员的疏忽,现在局域网内 ...

  4. hdu5029 Relief grain

    题目链接 树剖+线段树 将区间修改转化为单点修改,因为如果按DFS序进行修改,那么一定会对DFS序更大的点造成影响 #include<iostream> #include<vecto ...

  5. Dockfile基本语法

    FROM 功能为指定基础镜像,并且必须是第一条指令. 如果不以任何镜像为基础,那么可写为:FROM scratch. 接下来所写的指令将作为镜像的第一层开始. 格式: FROM <image&g ...

  6. django开发(二)

    1.django数据库操作---model的使用以及django自带的数据api django中已经做了ORM,表就是一个类class,表中的一个项就是一个对象object,很好用 1.1django ...

  7. 对于get系列className的不兼容

    function getClass(param){ if(id.getElementsByClassName){ return id.getElementsByClassName(param); }e ...

  8. vs2017添加引用出错:对COM组件的调用返回了错误HRESULT E_FAIL

    1.以管理员身份打开 Developer Command Prompt for VS 2017(vs2017开发人员命令提示符) 2.定位到你的vs2017的安装目录 例:E:\Program Fil ...

  9. vim自动补全头注释与说明

    做个笔记吧. .vimrc autocmd BufNewFile *.c,*.cpp,*.sh,*.py,*.java exec ":call SetTitle()" " ...

  10. Oracle 12c 的RMAN备份

    备份 rman只备份cdb 只备份CDB数据库需要具有SYSDBA或SYSBACKUP权限用户连接到CDB的root环境下,执行backupdatabase root命令即可完成对CDB的备份,方法如 ...