简体   繁体   中英

Set Spring profile in Tomcat web app with no web.xml file

I have a webapp that is a RestEASY JAX-RS application and that uses the latest servlet specifications, such as Java EE annotations so that I don't need to create a web.xml file.

The webapp is bundled as foobar.war and dumped into the webapps directory in Tomcat. In fact the same foobar.war is deployed twice in the same Tomcat instance, once as foobar.war and the other as foobar#demo.war (which maps it to foobar/demo as you know).

I configure each mounted webapp by placing conf/Catalina/localhost/foobar.xml and conf/Catalina/localhost/foobar#demo.xml files, that look like this:

<?xml version="1.0" encoding="UTF-8"?>
<Context>
  <Environment name="foo" type="java.lang.String" value="bar"/>
</Context>

In my JAX-RS application I pull in the value of foo from JNDI using java:comp/env/foo .

So now I added a Java-based Spring configuration named FooBarConfiguration. I load it in my JAX-RS application using new AnnotationConfigApplicationContext(FooBarConfiguration.class) . That all works fine.

So now I've added two profiles to FooBarConfiguration , one named foo and one named bar . But now... how do I tell the webapp which Spring profile to use? (Remember that I have no web.xml file.) Obviously I have to set spring.profiles.active somewhere. But where?

Because the documentation spoke of "environment" and "JNDI", I crossed my fingers and added an environment variable to conf/Catalina/localhost/foobar.xml :

  <Environment name="spring.profiles.active" type="java.lang.String" value="foo"/>

No luck.

I can't set a system property, because that will apply to all the webapps, and the idea here is that each foobar.war instance ( foobar.war and foobar#demo.war ) could each have a different profile specified.

I suppose I could manually pull it out of the Tomcat environment myself, using java:comp/env/spring.profiles.active , but then where do I set the value? (I thought maybe AnnotationConfigApplicationContext would have a constructor where I could set the profile, or at least have a profile setting, but that also seems to be missing.)

(Plus if I'm manually pulling out the setting from JNDI and setting it myself, I might as well switch to the more lightweight Guice and manually load the modules I want. I'm only using the humongous, clunky Spring because it promised to allow easy selection of profiles.)

How can I indicate, external to my WAR file, on a per-webapp basis, which Spring profile I'm using?

You can set active profiles in many ways. Since you were searching for it via AnnotationConfigApplicationContext constructor, the one described here in spring docs might suit you.

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setActiveProfiles("development");
ctx.refresh();

The solution is to use AnnotationConfigWebApplicationContext instead of StandardServletEnvironment .

The trick is to get Spring to use a StandardServletEnvironment , which looks in several places including JNDI java:comp/env/... for spring.profiles.active . See http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-property-source-abstraction .

My problem is that AnnotationConfigApplicationContext uses a StandardEnvironment , which only looks in a few places for the profile designation. Switching to a AnnotationConfigWebApplicationContext made Spring use a StandardServletEnvironment :

final AnnotationConfigWebApplicationContext webContext =
    new AnnotationConfigWebApplicationContext();
webContext.register(FooBarConfiguration.class);
webContext.refresh();

Now my webapp environment configuration in conf/Catalina/localhost/foobar.xml works:

<?xml version="1.0" encoding="UTF-8"?>
<Context>
  <Environment name="spring.profiles.active" type="java.lang.String" value="foo"/>
</Context>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM