为AbstractAnnotationConfigDispatcherServletInitializer设置可与@PropertySource一起使用的活动配置文件?


问题内容

我正在使用AbstractAnnotationConfigDispatcherServletInitializer来配置我的Web应用程序。我也有一个@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);
}

不过,我不确定在哪里可以做到这一点。据一个答案到一个相关的问题,这可能是在一个覆盖做过createRootApplicationContext方法在我的初始化类。但是,该答案还取决于设置配置文件之前加载的配置类。

我想做的事可能吗?如果是这样,怎么办?


问题答案:

覆盖createRootApplicationContextcreateServletApplicationContext对我不起作用。我遇到各种错误,例如非法状态异常和“
$
{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” 。