Setting an active profile for AbstractAnnotationConfigDispatcherServletInitializer that can be use with @PropertySource?

一个人想着一个人 提交于 2019-12-04 11:25:43

Overriding createRootApplicationContext or createServletApplicationContext was not working for me. I was getting various errors like illegal state exceptions and "${spring.profiles.active}" not being resolvable. Digging through the inheritance tree for AbstractAnnotationConfigDispatcherServletInitializer I devised the following solution:

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);
  }
}

Now you can create a configuration class like the following and it will work just fine:

@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;
  }
}

Of course, you would set the "your.profile.property" via VM options (-Dyour.profile.property=dev) or container properties (e.g. Tomcat container properties).

gabrielgiussi

Instead of

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

You also could do

@PropertySource( value = "classpath:application.properties" )

And use some maven plugin like 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>

And then run

mvn <lifecycle> -P production

There is some reason in favor of passing the active profile in a system property instead of a maven parameter?

With this configuration this solution worked for me:

@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
            }

        }
}

(*) This is an old plugin (release date 2009) so maybe we should find another that do the same work, but the idea is plugin for write properties + maven profiles.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!