spring配置xml文件_XML配置文件中的Spring配置文件

spring配置xml文件

我的上一个博客非常简单,因为它涵盖了我从Spring 3.0.x到Spring 3.1.x的轻松升级,最后我提到可以将Spring模式升级到3.1,以利用Spring的最新功能。 在今天的博客中,我将介绍这些功能中最酷的功能之一:Spring配置文件。 但是,在谈论如何实现Spring配置文件之前,我认为探索它们正在解决的问题是一个好主意,这是需要为不同的环境创建不同的Spring配置。 之所以会出现这种情况,通常是因为您的应用程序在其开发生命周期中需要连接到多个类似的外部资源,并且连接频率通常更高,并且这些“外部资源”通常不是数据库,尽管它们可以是JMS队列,Web服务,远程EJB等。

您的应用程序在运行之前必须工作的环境数量通常取决于几件事,包括您组织的业务流程,应用程序的规模以及它的“重要性”(即,如果您正在编写税收表)系统为您的国家/地区提供税收服务,则测试过程可能比为本地商店编写电子商务应用程序时更为严格。 为使您有所了解,以下是想到的所有不同环境的快速列表(可能不完整):

  1. 本地开发人员机器
  2. 开发测试机
  3. 测试团队功能测试机
  4. 集成测试机
  5. 克隆环境(实时副本)
  6. 生活

这不是一个新问题,通常可以通过为每个环境创建一组Spring XML和属性文件来解决。 XML文件通常包含一个导入其他环境特定文件的主文件。 然后在编译时将它们耦合在一起以创建不同的WAR或EAR文件。 这种方法已经使用了多年,但确实存在一些问题:

  1. 这是非标准的。 每个组织通常都有自己的解决方案,没有两种方法可以完全相同/
  2. 很难实现,为错误留出了很大的空间。
  3. 必须为每个环境创建一个不同的WAR / EAR文件并将其部署在每个环境上,这需要花费时间和精力,这可能会花费更多的时间来编写代码。

Spring bean配置中的差异通常可以分为两部分。 首先,存在特定于环境的属性,例如URL和数据库名称。 通常使用PropertyPlaceholderConfigurer类和相关的$ {}标记将它们注入到Spring XML文件中。

<bean id='propertyConfigurer' class='org.springframework.beans.factory.config.PropertyPlaceholderConfigurer'><property name='locations'><list><value>db.properties</value></list></property></bean>

其次,有特定于环境的bean类,例如数据源,它们通常根据您连接数据库的方式而有所不同。

例如,在开发中,您可能具有:

<bean id='dataSource' class='org.springframework.jdbc.datasource.DriverManagerDataSource'><property name='driverClassName'><value>${database.driver}</value></property><property name='url'><value>${database.uri}</value></property><property name='username'><value>${database.user}</value></property><property name='password'><value>${database.password}</value></property></bean>

…无论是测试还是现场直播,您只要写:

<jee:jndi-lookup id='dataSource' jndi-name='jdbc/LiveDataSource'/>

Spring准则指出,仅应在上面的第二个示例中使用Spring概要文件:特定于Bean的类,并且您应继续使用PropertyPlaceholderConfigurer初始化简单的Bean属性; 但是,您可能希望使用Spring配置文件将特定于环境的PropertyPlaceholderConfigurer注入到Spring上下文中。

话虽如此,我将在示例代码中打破这一约定,因为我想用最简单的代码来演示Spring配置文件的功能。

Spring配置文件和XML配置
在XML配置方面,Spring 3.1在spring-beans模式的bean元素中引入了新的profile属性:

<beans profile='dev'>

在不同环境中启用和禁用配置文件时,此配置文件属性充当开关。

为了进一步解释所有这些,我将使用一个简单的想法,即您的应用程序需要加载一个人员类,并且该人员类包含不同的属性,具体取决于您的程序在其上运行的环境。

Person类非常简单,看起来像这样:

public class Person {private final String firstName;private final String lastName;private final int age;public Person(String firstName, String lastName, int age) {this.firstName = firstName;this.lastName = lastName;this.age = age;}public String getFirstName() {return firstName;}public String getLastName() {return lastName;}public int getAge() {return age;}}

…并在以下XML配置文件中定义:

<?xml version='1.0' encoding='UTF-8'?>
<beans xmlns='http://www.springframework.org/schema/beans'xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd'profile='test1'><bean id='employee' class='profiles.Person'><constructor-arg value='John' /><constructor-arg value='Smith' /><constructor-arg value='89' /></bean>
</beans>

…和

<?xml version='1.0' encoding='UTF-8'?>
<beans xmlns='http://www.springframework.org/schema/beans'xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd'profile='test2'><bean id='employee' class='profiles.Person'><constructor-arg value='Fred' /><constructor-arg value='ButterWorth' /><constructor-arg value='23' /></bean>
</beans>

…分别称为test-1-profile.xmltest-2-profile.xml (请记住这些名称,它们在以后很重要)。 如您所见,配置的唯一区别是名字,姓氏和年龄属性。

不幸的是,仅仅定义个人资料还不够,您必须告诉Spring您正在加载哪个个人资料。 这意味着遵循旧的“标准”代码现在将失败:

@Test(expected = NoSuchBeanDefinitionException.class)public void testProfileNotActive() {// Ensure that properties from other tests aren't setSystem.setProperty('spring.profiles.active', '');ApplicationContext ctx = new ClassPathXmlApplicationContext('test-1-profile.xml');Person person = ctx.getBean(Person.class);String firstName = person.getFirstName();System.out.println(firstName);}

幸运的是,有几种选择配置文件的方法,在我看来,最有用的方法是使用“ spring.profiles.active”系统属性。 例如,以下测试现在将通过:

System.setProperty('spring.profiles.active', 'test1');ApplicationContext ctx = new ClassPathXmlApplicationContext('test-1-profile.xml');Person person = ctx.getBean(Person.class);String firstName = person.getFirstName();assertEquals('John', firstName);

显然,您不想像我上面那样对代码进行硬编码,最佳实践通常意味着将系统属性定义与应用程序分开。 这使您可以选择使用简单的命令行参数,例如:

-Dspring.profiles.active='test1'

…或通过添加

# Setting a property value
spring.profiles.active=test1

Tomcat的catalina.properties

因此,仅此而已:您可以使用bean元素配置文件属性创建Spring XML配置文件,并通过将spring.profiles.active系统属性设置为配置文件的名称来打开要使用的配置文件

获得一些额外的灵活性

但是,这还不是故事的结局,因为Spring的Guy已添加了许多以编程方式加载和启用配置文件的方式-如果您愿意的话。

@Testpublic void testProfileActive() {ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext('test-1-profile.xml');ConfigurableEnvironment env = ctx.getEnvironment();env.setActiveProfiles('test1');ctx.refresh();Person person = ctx.getBean('employee', Person.class);String firstName = person.getFirstName();assertEquals('John', firstName);}

在上面的代码中,我使用了新的ConfigurableEnvironment类来激活“ test1”配置文件。

@Testpublic void testProfileActiveUsingGenericXmlApplicationContextMultipleFilesSelectTest1() {GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();ConfigurableEnvironment env = ctx.getEnvironment();env.setActiveProfiles('test1');ctx.load('*-profile.xml');ctx.refresh();Person person = ctx.getBean('employee', Person.class);String firstName = person.getFirstName();assertEquals('John', firstName);}

但是,Spring专家们建议您使用GenericApplicationContext类而不是ClassPathXmlApplicationContextFileSystemXmlApplicationContext,因为这样可以提供更大的灵活性。 例如,在上面的代码中,我已经使用GenericApplicationContextload(...)方法使用通配符来加载许多配置文件:

ctx.load('*-profile.xml');

还记得以前的文件名吗? 这将同时加载test-1-profile.xmltest-2-profile.xml

配置文件还具有额外的灵活性,可让您一次激活多个。 如果看下面的代码,您会看到我正在激活我的test1test2配置文件:

@Testpublic void testMultipleProfilesActive() {GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();ConfigurableEnvironment env = ctx.getEnvironment();env.setActiveProfiles('test1', 'test2');ctx.load('*-profile.xml');ctx.refresh();Person person = ctx.getBean('employee', Person.class);String firstName = person.getFirstName();assertEquals('Fred', firstName);}

请注意,在本示例中,我有两个ID为“ employee”的bean,并且无法分辨哪个是有效的,并且应该优先。 从我的测试中,我猜想读取的第二个将覆盖或屏蔽对第一个的访问。 没关系,因为您不应该拥有多个具有相同名称的bean –激活多个配置文件时需要提防。

最后,可以做的更好的简化之一是使用嵌套的<beans />元素。

<?xml version='1.0' encoding='UTF-8'?>
<beans xmlns='http://www.springframework.org/schema/beans'xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:context='http://www.springframework.org/schema/context'xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd'><beans profile='test1'><bean id='employee1' class='profiles.Person'><constructor-arg value='John' /><constructor-arg value='Smith' /><constructor-arg value='89' /></bean></beans><beans profile='test2'><bean id='employee2' class='profiles.Person'><constructor-arg value='Bert' /><constructor-arg value='William' /><constructor-arg value='32' /></bean></beans></beans>

尽管以最小的灵活性为代价,但是这消除了通配符和加载多个文件的所有繁琐处理。

我的下一个博客通过查看与新的@Profile注释结合使用的@Configuration注释,总结了我对Spring概要文件的了解,因此,稍后会有更多介绍。

参考:来自Captain Debug博客博客的JCG合作伙伴 Roger Hughes提供的在XML Config中使用Spring Profiles 。


翻译自: https://www.javacodegeeks.com/2012/08/spring-profiles-in-xml-config-files.html

spring配置xml文件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/353658.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数组指针和指针数组的区别

数组指针&#xff08;也称行指针&#xff09; 定义 int (*p)[n]; ()优先级高&#xff0c;首先说明p是一个指针&#xff0c;指向一个整型的一维数组&#xff0c;这个一维数组的长度是n&#xff0c;也可以说是p的步长。也就是说执行p1时&#xff0c;p要跨过n个整型数据的长度。 如…

用JS写的取存款功能

console.log("请输入用户名&#xff1a;");let username readline.question(); // 接收用户输入的用户名console.log("请输入密码&#xff1a;");let password readline.question(); // 接收用户输入的密码let arr [["123", "123…

您在2016年OpenStack峰会上错过的事情

今年我第一次参加了4月25日至29日在德克萨斯州奥斯汀举行的OpenStack峰会。 今天结束了&#xff0c;我要回家了&#xff0c;我想回顾一下&#xff0c;从我的角度分享你错过的事情。 作为以应用程序开发人员为重点的技术传播者&#xff0c;转移到包含Red Hat产品组合的基础架构…

HDU1069 最长上升子序列

emm。。。。矩形嵌套 还记得吗。。。。就是它。。。 直接贴代码了。。。。 import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Scanner;public class Main{final static int maxn 1000000;…

linux 中配置假域名来测试

1.linux中配置假域名 找到hosts文件进行编辑 命令&#xff1a;vim /etc/hosts 配置&#xff1a; #centos&#xff08;本机IP&#xff09;192.168.1.179 www.imooc.com&#xff08;假域名&#xff0c;自己设置&#xff09;192.168.1.179 image.imooc.com192.168.1.179 s.imooc.c…

C/C++中的常量指针与指针常量

常量指针 常量指针是指向常量的指针&#xff0c;指针指向的内存地址的内容是不可修改的。 常量指针定义“const int *p&a;”告诉编译器&#xff0c;*p是常量&#xff0c;不能将*p作为左值进行操作。但这里的指针p还是一个变量&#xff0c;它的内容存放常量的地址&#xff0…

基于javafx的五子棋_JavaFX中基于表达式的PathTransitions

基于javafx的五子棋在JavaFX中&#xff0c;您可以使用PathTransition对象为路径上的节点设置动画。 PathTransitions使用Shape对象来描述它们需要沿其动画的路径。 JavaFX提供了各种类型的形状&#xff08;例如&#xff0c;多边形&#xff0c;圆形&#xff0c;多边形&#xff0…

ES6三种暴露方法

1.多行暴露&#xff08;分行暴露&#xff09; 导出 //test.js export function test1(){console.log(测试分别导出test1); } export function test2(){console.log(测试分别导出test2); } 导入&#xff1a; //index.js import {test1, test2} from ./test.js //文件路径二&…

shell获取当前执行脚本的路径

filepath$(cd "$(dirname "$0")"; pwd)脚本文件的绝对路径存在了环境变量filepath中&#xff0c;可以用echo $filepath查看完整路径在shell中&#xff1a;$0: 获取当前脚本的名称$#: 传递给脚本的参数个数$$: shell脚本的进程号$1, $2, $3...&#xff1a;脚…

MANIFEST.MF文件详解

参考百度百科的解释如下&#xff1a; http://baike.baidu.com/item/MANIFEST.MF MANIFEST.MF&#xff1a;这个 manifest 文件定义了与扩展和包相关的数据。单词“manifest”的意思是“显示” ### MANIFEST.MF文件介绍------------------------------ 主要包含3个部分 - Manifes…

Drools 6.4.0.Final提供

最新和最出色的Drools 6.4.0.Final版本现已可供下载。 这是我们先前构建的增量版本&#xff0c;对核心引擎和Web工作台进行了一些改进。 您可以在此处找到更多详细信息&#xff0c;下载和文档&#xff1a; Drools网站 资料下载 文献资料 发行说明 请阅读下面的一些发行要…

Linux Shell中各种分号和括号的用法总结

[日期&#xff1a;2011-02-21] 来源&#xff1a;Linux社区 作者&#xff1a;破烂熊 [字体&#xff1a;大 中 小] 各种括号的用法总结如下 1.Shell中变量的原形&#xff1a;${var} 大家常见的变量形式都是$var 2.命令替换$(cmd) 命令替换$(cmd)和符号cmd(注意这不是单引号…

软考解析:2014年下半年下午试题

软考解析&#xff1a;2014年下半年下午试题 第一题&#xff1a;数据流图 第四题&#xff1a;算法题 第五题&#xff1a;Java设计模式 转载于:https://www.cnblogs.com/MrSaver/p/9073778.html

malloc()参数为0的情况

问题来自于《程序员面试宝典&#xff08;第三版&#xff09;》第12.2节问题9&#xff08;这里不评价《程序员面试宝典》&#xff0c;就题论题&#xff09;&#xff1a; 下面的代码片段输出是什么&#xff1f;为什么&#xff1f; char *ptr;if((ptr (char *)malloc(0))NULL)put…

铁乐学python_Day42_锁和队列

铁乐学python_Day42_锁和队列 例&#xff1a;多个线程抢占资源的情况 from threading import Thread import timedef work():global ntemp ntime.sleep(0.1)n temp - 1if __name__ __main__:n 100l []for i in range(100):p Thread(targetwork)l.append(p)p.start()for p…

hibernate 懒加载_Hibernate懒/急加载示例

hibernate 懒加载这篇文章将重点讨论为什么以及如何在应用程序中使用称为LAZY和EAGER加载的概念&#xff0c;以及如何使用Spring的Hibernate模板以EAGER方式加载LAZY实体。 当然&#xff0c;正如标题本身所暗示的那样&#xff0c;我们将通过一个示例来说明这一点。 场景就是这样…

C++ 关键字typeid

转载网址&#xff1a;http://www.cppblog.com/smagle/archive/2010/05/14/115286.aspx 在揭开typeid神秘面纱之前&#xff0c;我们先来了解一下RTTI&#xff08;Run-Time Type Identification&#xff0c;运行时类型识别&#xff09;&#xff0c;它使程序能够获取由基指针或引用…

使用Apache Camel进行负载平衡

在此示例中&#xff0c;我们将向您展示如何使用Apache Camel作为系统的负载平衡器。 在计算机世界中&#xff0c;负载均衡器是一种充当反向代理并在许多服务器之间分配网络或应用程序流量的设备。 负载平衡器用于增加容量&#xff08;并发用户&#xff09;和应用程序的可靠性。…

Java8-Guava实战示例

示例一&#xff1a; 跟示例三对比一下&#xff0c;尽量用示例三 List<InvoiceQueryBean> invoiceQueryBeanList new ArrayList<>(); List<String> invoices Lists.newArrayList(Iterators.transform(invoiceQueryBeanList.iterator(), new Function<Inv…

java项目构建部署包

博客分类&#xff1a; JAVA Java 工程在生产环境运行时&#xff0c;一般需要构建成一个jar&#xff0c;同时在运行时需要把依赖的jar添加到classpath中去&#xff0c;如果直接运行添加classpath很不方便&#xff0c;比较方便的是创建一个shell脚本。在公司项目中看到把工程代码…