Profiles i Spring 2.5/3.0
Tidigare beskrev Tommy Wassgren hur man kan använda profiles i Spring 3.1 för att definiera olika kör-profiler. T.ex. en profil för utveckling och en för produktion, vilka man enkelt kan växla mellan m.h.a. en jvm parameter. Kruxet är dock att 3.1 inte är släppt, så i väntan på detta vad gör man då om sitter i t.ex. Spring 2.5?
**
Exempel 1
I spring-kontexten definierar vi en PropertyPlaceholderConfigurer. Denna gör att vi kan använda variabelreferenser som substitueras med värden som i första hand är tagna från Javas system properties och i andra hand från myapp.properties.
<bean class=
"org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:myapp.properties</value>
</property>
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
</bean>
Vi har också två stycken bönor: developmentHelloMessage och productionHelloMessage. I exemplet är det två enkla strängar men de kan vara mer komplexa än så. Notera också att vi andvänder lazy-init för profilbönorna för att endast instansiera bönorna i den valda profilen.
<bean id="developmentHelloMessage" class="java.lang.String" lazy-init="true">
<constructor-arg type="java.lang.String" value="DEV: Hello, world!" />
</bean>
<bean id="productionHelloMessage" class="java.lang.String" lazy-init="true">
<constructor-arg type="java.lang.String" value="PROD: Hello, world!" />
</bean>
<alias name="${myapp.profile}HelloMessage" alias="helloMessage" />
Sist kommer ett alias till en av bönorna. Märk att aliaset innehåller en variabelreferens. I filen myapp.properties sätter vi standardprofilen till development:
myapp.profile=development
Java-koden nedan kan exekveras utan några speciella argument och kör då enligt standardprofilen.
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("myapp-context.xml");
System.out.println(context.getBean("helloMessage"));
För att explicit sätta profil så lägg till följande JVM-arg:
-Dmyapp.profile=production
Exempel 2
I detta exempel visar jag hur man kan på ett konfigurerbart sätt kan växla mellan Oracles Universal Connection Pool eller Apaches DBCP genom att sätta egenskapen myapp.datasource
till upc
eller dbcp
.
<bean id="ucpDataSource" oracle.ucp.jdbc.PoolDataSourceFactory" factory-method="getPoolDataSource" lazy-init="true">
<property name="user" value="${myapp.datasource.username}" />
<property name="password" value="${myapp.datasource.password}" />
<property name="URL" value="${myapp.datasource.url}" />
<property name="connectionFactoryClassName" value="${myapp.datasource.ucp.connectionFactory}" />
<property name="minPoolSize" value="${myapp.datasource.minPoolSize}" />
<property name="maxPoolSize" value="${myapp.datasource.maxPoolSize}" />
</bean>
<bean id="dbcpDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" lazy-init="true">
<property name="username" value="${myapp.datasource.username}" />
<property name="password" value="${myapp.datasource.password}" />
<property name="url" value="${myapp.datasource.url}" />
<property name="driverClassName" value="${myapp.datasource.dbcp.driver}"/>
<property name="initialSize" value="${myapp.datasource.minPoolSize}" />
<property name="maxActive" value="${myapp.datasource.maxPoolSize}" />
<property name="maxIdle" value="${myapp.datasource.minPoolSize}" />
</bean>
<alias name="${myapp.datasource}DataSource" alias="dataSource"/>
myapp.properties:
myapp.datasource=ucp
myapp.datasource.username=MYAPP
myapp.datasource.password=MYAPP
myapp.datasource.url=jdbc:oracle:thin:@myServer:1521:myDB
myapp.datasource.minPoolSize=5
myapp.datasource.maxPoolSize=20
myapp.datasource.dbcp.driver=oracle.jdbc.driver.OracleDriver
myapp.datasource.ucp.connectionFactory=oracle.jdbc.pool.OracleDataSource
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("myapp-context.xml");
System.out.println(context.getBean("dataSource"));
Alias eller BeanReferenceFactoryBean
Alias-metoden funkar så länge man inte är tvungen att omdefiniera en existerande böna med samma namn. I så fall måste man använda sig av BeanReferenceFactoryBean-klassen. T.ex. om product-defaults.xml också definierar en böna vid namn helloMessage så kan inte alias användas.
<import resource="classpath:product-defaults.xml"/>
<bean id="helloMessage" class="org.springframework.beans.factory.config.BeanReferenceFactoryBean">
<property name="targetBeanName" value="${myapp.profile}HelloMessage" />
</bean>