Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 为AbstractAnnotationConfigDispatcherServletInitializer设置可与@PropertySource一起使用的活动配置文件?_Spring_Spring Mvc_Spring 3 - Fatal编程技术网

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

Spring 为AbstractAnnotationConfigDispatcherServletInitializer设置可与@PropertySource一起使用的活动配置文件?,spring,spring-mvc,spring-3,Spring,Spring Mvc,Spring 3,我正在使用AbstractAnnotationConfigDispatcherServletInitializer配置我的web应用程序。我还有一个@Configuration类,用于创建一些bean。在这个类中,我使用@PropertySource注释为各种设置(例如数据库连接详细信息)加载属性文件 目前,我在Ant任务中使用Maven概要文件为我的运行时环境创建正确的属性文件。也就是说,我让Maven在构建时将“prod.properties”或“dev.properties”移动到“app

我正在使用
AbstractAnnotationConfigDispatcherServletInitializer
配置我的web应用程序。我还有一个
@Configuration
类,用于创建一些bean。在这个类中,我使用
@PropertySource
注释为各种设置(例如数据库连接详细信息)加载属性文件

目前,我在Ant任务中使用Maven概要文件为我的运行时环境创建正确的属性文件。也就是说,我让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);
}
不过,我不确定我在哪里可以做到这一点。根据一个相关的问题,这可以通过重写我的initializer类中的
createRootApplicationContext
方法来完成。但是,这个答案还依赖于在设置概要文件之前加载的配置类


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

重写
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”

@PropertySource( value = "classpath:application-${spring.profiles.active}.properties" )
你也可以

@PropertySource( value = "classpath:application.properties" )
并使用一些maven插件,比如属性maven plugin(*)


(*)这是一个旧插件(发布日期为2009年),所以也许我们应该找到另一个做同样工作的插件,但想法是针对write properties+maven profiles的插件。

@Charles,你为什么要删除[spring-3.2]标签?这很重要。当现有版本标记已覆盖相同区域时,3.2.New版本标记之前不存在主初始值设定项类。
[spring-3]
标签wiki摘录说它适用于所有3.x版本的spring。包括3.2。新特性不会破坏足够的内容,从而严格要求在此处添加新标签。(还要记住主版本标签的问题计数——小于600。碎片是不好的。)重新阅读链接。“在我看来,唯一应该使用c#-4.0标记的问题是那些专门询问4.0中添加的功能细节的问题。”——我问的是3.2的一个特定功能。在
createRootApplicationContext
中,注册了配置类,但上下文尚未刷新。@SotiriosDelimanolis感谢您澄清这一点,但我无法让它在覆盖该方法时起作用。+1我认为它不起作用的原因是,尽管上下文未刷新,但您的
@Configuration
类”元数据已加载(我也对此进行了更多研究)。如果类注册后未声明,
@PropertySource
的占位符,则无法解析该占位符。在解决此解决方案之前,我在覆盖中重新实现了默认方法,添加了配置文件检测,设置了活动配置文件,注册了配置类,并刷新了上下文。春天一点也没有。
   <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
@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
            }

        }
}