I have been experimenting with using Spring 3.1's bean definition profiles and nested beans. I had hoped that I could define different beans depending on the active profile. Consider the following heavily over simplified example such that my Spring context contains something like
<bean id="say" class="test.Say" p:hello-ref="hello"/>
<beans profile="prod">
<bean id="hello" class="test.Hello" p:subject="Production!"/>
</beans>
<beans profile="dev">
<bean id="hello" class="test.Hello" p:subject="Development!"/>
</beans>
I get the following error:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'say' defined in class path resource [applicationContext.xml]: Cannot resolve reference to bean 'hello' while setting bean property 'hello'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'hello' is defined at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328) at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1360) aJava Result: 1
I was expecting that the hello bean would be defined according to the active Maven profile (in my case prod or dev). I'm starting to think that the Spring active profiles (spring.profiles.active) may be completely unrelated to Maven profiles.
Could somebody please explain where I am going wrong? (Is this even possible using profiles?).
I was expecting that the hello bean would be defined according to the active Maven profile (in my case prod or dev). I'm starting to think that the Spring active profiles (spring.profiles.active) may be completely unrelated to Maven profiles.
That's true, they are unrelated.
Here is how you can fix it:
Make sure that the web.xml
that you have in src/main/webapp/WEB-INF/
folder has the following context setting:
<context-param>
<param-name>spring.profile.active</param-name>
<param-value>${profileName}</param-value>
</context-param>
And then make sure that the maven-war-plugin
has filtering turned on for the web.xml
:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
</configuration>
</plugin>
And then lastly in your profiles:
<profiles>
<profile>
<id>dev</id>
<properties>
<profileName>dev</profileName>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<profileName>prod</profileName>
</properties>
</profile>
</profiles>
You could also add a default value in the normal properties section:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<profileName>dev</profileName>
</properties>
So if you run without the -P
option the dev
spring profile will be used.
When running mvn package
the web.xml
will have the correct value for the spring.profile.active
.