Spring笔记之根据开发环境装配不同bean

开发中遇到的最大挑战之一,是环境的变化。数据库配置、加密算法以及与外部系统的集成等都和开发环境相关。

# 编译时定义bean

以数据库为例,在开发的时候,会倾向于使用测试数据,比如在Spring的配置类里,可能会像下面这样配置EmbeddedDatabaseBuilder(),以创建一个DataSource的bean:

这样,在开发环境中,可以根据需要,在schema.sql和test-data.sql中增加模拟数据。生产环境不能这么做,而更倾向于使用JNDI,创建一个DataSource的bean:

使用JNDI,容器可以决定怎样创建DataSource,包括从连接池中交接DataSource。当然,这些对生产环境很有用,但对开发情况下的测试以及简单的集成测试来说,一般并不需要。

而QA环境可能想用另外的配置:

可以使用例如Maven profiles的方式,在不同环境进行重新编译(build)来解决和环境相关的问题,但是,重新build可能引入新的bug,而这是灾难性的。

# 运行时生成bean

Spring的方案和上述方案差不多,只是改成了运行时配置。生产环境和开发环境使用同一套代码,避免在发布时,因为更改java代码,重新编译代码引起问题。可以在方法或类上加Profile标签,这样,只有环境满足条件时,才会生成相应的bean,而没有加这个标签的bean是在任何条件下都会生成的。

也可以使用XML做到这一点,本笔记略。

Profile 标签的定义如下:

可以看出,Profile标签是运行时生效,并且支持标注在类和方法上,同时,被@Conditional标注,表明只有满足ProfileCondition条件时,才生效。ProfileCondition定义如下:

可以看出,判断是否匹配的逻辑是,从@Profile标签中获取可接受的Profile值列表(可以有多个值),再从上下文中获取环境,判断环境中当前是否包含这些Profile值,以判断当前环境是否满足条件。那么,如何在环境中设置当前Profile值呢?

# 在环境中设置当前Profile

Spring使用spring.profiles.active和spring.profiles.default属性来确定当前Profile。spring.profiles.active不为空时,spring.profiles.active的值是当前Profile,spring.profiles.active的值为空时,spring.profiles.default的值是当前Profile,两个都为空时,则所有加了Profile标签的bean都不生成,没有加Profile标签的bean才会生成。可以使用以下方式设置这两个属性:

* 作为DispatcherServlet的参数

* 作为web应用上下文的参数

* 作为JNDI的entry

* 作为环境变量

* 作为JVM系统属性

* 在一个集成测试类上使用@ActiveProfiles标签

你可以自己选择最合适的方式。

# 测试Profile以指定环境

当代码里使用了Profile来指定环境相关的操作后,有时候需要在测试环境中模拟与生产环境相同的Profile,来进行测试。Spring提供了@ActiveProfiles标签,指定测试程序运行时的当前Profile。下面,在添加开发环境配置初始化sql文件schema.sql和test-data.sql后,以及上文中的DataSourceConfig的配置类后,进行数据库测试(这些代码都可以在[官方样例](
https://manning-content.s3.amazonaws.com/download/9/ef4e0ef-b7bd-4ab8-857d-eb635d18d425/SpringiA4_SourceCode.zip)下载)。

schema.sql如下:

test-data.sql如下:

测试代码如下:

可以看到,开发环境的dataSource生成成功,并且能够正确的查询数据。而生产环境由于没有在JNDI中配置数据库,dataSource为空。

读到了这里,给自己点一个赞吧(^_^) 如果您喜欢这篇文章,可以考虑收藏和分享给更多朋友哦,在此拜谢orz!偷偷告诉您一个小秘密:收藏和分享后,在PC上看IT文章,观感更好哦。您可以在浏览器输入toutiao.com访问今日头条,也可以直接访问我的独立博客tantanit.com。这篇文章的地址是
http://tantanit.com/springinacton4-du-shu-bi-ji-zhi-gen-ju-kai-fa-huan-jing-zhuang-pei-bean/

声明:本站部分文章内容及图片转载于互联 、内容不代表本站观点,如有内容涉及侵权,请您立即联系本站处理,非常感谢!

(0)
上一篇 2016年10月17日
下一篇 2016年10月19日

相关推荐