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>