XML配置文件中的Spring配置文件
您的應用程序在運行之前必須工作的環境數量通常取決于幾件事,包括您組織的業務流程,應用程序的規模以及它的“重要性”(即,如果您正在編寫稅收表)系統為您的國家/地區提供稅收服務,那么測試過程可能比為本地商店編寫電子商務應用程序時更為嚴格。 為使您有所了解,以下是想到的所有不同環境的快速列表(可能不完整):
這不是一個新問題,通常可以通過為每個環境創建一組Spring XML和屬性文件來解決。 XML文件通常包含一個導入其他環境特定文件的主文件。 然后在編譯時將它們耦合在一起以創建不同的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屬性:
當在不同環境中啟用和禁用配置文件時,此配置文件屬性充當開關。
為了進一步解釋所有這些,我將使用一個簡單的想法,即您的應用程序需要加載一個人員類,并且該人員類包含不同的屬性,具體取決于您的程序在其上運行的環境。
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.xml和test-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類而不是ClassPathXmlApplicationContext和FileSystemXmlApplicationContext,因為這樣可以提供更大的靈活性。 例如,在上面的代碼中,我已經使用GenericApplicationContext的load(...)方法使用通配符來加載許多配置文件:
ctx.load('*-profile.xml');還記得以前的文件名嗎? 這將同時加載test-1-profile.xml和test-2-profile.xml 。
配置文件還具有額外的靈活性,可讓您一次激活多個。 如果看下面的代碼,您會看到我正在激活我的test1和test2配置文件:
@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);}當心,在本示例中,我有兩個標識為“ 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
總結
以上是生活随笔為你收集整理的XML配置文件中的Spring配置文件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (linux .os)
- 下一篇: Spring Security使用Hib