我正在使用AbstractAnnotationConfigDispatcherServletInitializer
配置我的网络应用程序。我还有一个@Configuration
类用于创建一些bean。在本课程中,我使用@PropertySource
注释来加载各种设置的属性文件(例如数据库连接详细信息)。
目前,我使用Maven配置文件和Ant任务为我的运行时环境创建正确的属性文件。也就是说,我让Maven在构建时将“prod.properties”或“dev.properties”移动到“application.properties”(该类使用)。我想要做的是使用Spring配置文件来消除这种情况。我希望能够做到以下几点:
@PropertySource( value = "classpath:/application-${spring.profiles.active}.properties")
我还想在不使用任何XML的情况下设置配置文件。所以我需要根据系统属性的存在来设置配置文件。例如,
String currentEnvironment = systemProperties.getProperty("current.environment");
if (currentEnvironment == null) {
((ConfigurableEnvironment)context.getEnvironment()).setActiveProfiles("production");
} else {
((ConfigurableEnvironment)context.getEnvironment()).setActiveProfiles(currentEnvironment);
}
但是,我不知道我能在哪里做到这一点。根据{{3}}相关问题,可以在我的初始化程序类中覆盖createRootApplicationContext
方法。但是,该答案还依赖于在设置配置文件之前加载的配置类。
我想做的是什么?如果是这样,怎么样?
答案 0 :(得分:6)
覆盖createRootApplicationContext
或createServletApplicationContext
对我不起作用。我遇到了各种错误,例如非法状态异常和“$ {spring.profiles.active}”无法解析。挖掘AbstractAnnotationConfigDispatcherServletInitializer
的继承树我设计了以下解决方案:
public class ApplicationInitializer
extends AbstractAnnotationConfigDispatcherServletInitializer
{
@Override
public void onStartup(ServletContext context) throws ServletException {
super.onStartup(context);
String activeProfile = System.getProperty("your.profile.property");
if (activeProfile == null) {
activeProfile = "prod"; // or whatever you want the default to be
}
context.setInitParameter("spring.profiles.active", activeProfile);
}
}
现在您可以创建如下所示的配置类,它可以正常工作:
@Configuration
@PropertySource( value = "classpath:application-${spring.profiles.active}.properties" )
public class MyAppBeans {
@Autowired
private Environment env;
@Bean
public Object coolBean() {
String initParam = this.env.getProperty("cool.bean.initParam");
...
return coolBean;
}
}
当然,您可以通过VM选项(-Dyour.profile.property=dev
)或容器属性(例如Tomcat容器属性)设置“your.profile.property”。
答案 1 :(得分:0)
而不是
@PropertySource( value = "classpath:application-${spring.profiles.active}.properties" )
你也可以
@PropertySource( value = "classpath:application.properties" )
并使用一些maven插件,例如properties-maven-plugin(*)
<build>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>write-active-profile-properties</goal>
</goals>
<configuration>
<outputFile>src/main/resources/application.properties</outputFile>
</configuration>
</execution>
</executions>
</plugin>
</build>
<profiles>
<profile>
<id>production</id>
<properties>
<profiles>prod</profiles>
<propertyOne>...</propertyOne>
<propertyTwo>...</propertyTwo>
</properties>
</profile>
<profile>
<id>development</id>
<properties>
<profiles>dev</profiles>
<propertyOne>...</propertyOne>
</properties>
</profile>
</profiles>
然后运行
mvn <lifecycle> -P production
有一些理由支持在系统属性中传递活动配置文件而不是maven参数吗?
使用此配置this solution为我工作:
@Configuration
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{
protected WebApplicationContext createRootApplicationContext() {
WebApplicationContext context = super.createRootApplicationContext();
((ConfigurableEnvironment) context.getEnvironment()).setActiveProfiles(profiles());
return context;
}
public String[] profiles() {
InputStream input = getClass().getClassLoader()
.getResourceAsStream("application.properties");
Properties properties = new Properties();
try {
properties.load(input);
return properties.getProperty("profiles").split(",");;
} catch (IOException e) {
e.printStackTrace();
String[] defaultProfiles = {"dev"};
return defaultProfiles;
// I really think that here we shouldn't return a default profile
}
}
}
(*)这是一个旧插件(发布日期为2009年),所以也许我们应该找另一个做同样工作的插件,但想法是写属性+ maven配置文件的插件。