简体   繁体   English

在没有web.xml文件的Tomcat Web应用程序中设置Spring配置文件

[英]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. 我有一个web应用程序,它是RestEASY JAX-RS应用程序,并且使用最新的servlet规范,例如Java EE注释,因此不需要创建web.xml文件。

The webapp is bundled as foobar.war and dumped into the webapps directory in Tomcat. 该webapp捆绑为foobar.war并转储到Tomcat的webapps目录中。 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). 实际上,同一foobar.war在同一Tomcat实例中部署了两次,一次是foobar.war ,另一次是foobar#demo.war (如您所知将其映射到foobar/demo )。

I configure each mounted webapp by placing conf/Catalina/localhost/foobar.xml and conf/Catalina/localhost/foobar#demo.xml files, that look like this: 我通过放置conf/Catalina/localhost/foobar.xmlconf/Catalina/localhost/foobar#demo.xml文件来配置每个已安装的Webapp,如下所示:

<?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 . 在我的JAX-RS应用程序中,我使用java:comp/env/foo从JNDI中提取foo的值。

So now I added a Java-based Spring configuration named FooBarConfiguration. 因此,现在我添加了一个名为FooBarConfiguration的基于Java的Spring配置。 I load it in my JAX-RS application using new AnnotationConfigApplicationContext(FooBarConfiguration.class) . 我使用new AnnotationConfigApplicationContext(FooBarConfiguration.class)其加载到我的JAX-RS应用程序中。 That all works fine. 一切正常。

So now I've added two profiles to FooBarConfiguration , one named foo and one named bar . 因此,现在我在FooBarConfiguration添加了两个配置文件,一个名为foo ,一个名为bar But now... how do I tell the webapp which Spring profile to use? 但是现在...我该如何告诉webapp使用哪个Spring配置文件? (Remember that I have no web.xml file.) Obviously I have to set spring.profiles.active somewhere. (请记住,我没有web.xml文件。)显然,我必须在某个地方设置spring.profiles.active 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 : 因为文档中提到了“环境”和“ JNDI”,所以我conf/Catalina/localhost/foobar.xmlconf/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. 我无法设置系统属性,因为这将适用于所有 foobar.war应用程序,这里的想法是每个foobar.war实例( foobar.warfoobar#demo.war )都可以指定不同的配置文件。

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? 我想我可以使用java:comp/env/spring.profiles.active手动将其自己从Tomcat环境中java:comp/env/spring.profiles.active ,但是在哪里设置该值呢? (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.) (我以为AnnotationConfigApplicationContext可能会有一个构造函数,可以在其中设置概要文件,或者至少具有概要文件设置,但这似乎也没有。)

(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.) (另外,如果我要手动从JNDI中取出设置并自己进行设置,我不妨切换到更轻量级的Guice并手动加载所需的模块。我只使用笨拙,笨拙的Spring,因为它承诺允许轻松选择配置文件。)

How can I indicate, external to my WAR file, on a per-webapp basis, which Spring profile I'm using? 在我的WAR文件外部,如何在每个Web应用程序的基础上指示我正在使用哪个Spring配置文件?

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构造函数进行搜索的,因此Spring文档此处描述的构造函数可能适合您。

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

The solution is to use AnnotationConfigWebApplicationContext instead of StandardServletEnvironment . 解决方案是使用AnnotationConfigWebApplicationContext代替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 . 诀窍是让Spring使用StandardServletEnvironment ,它在包括spring.profiles.active JNDI java:comp/env/...在内的多个地方进行spring.profiles.active See http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-property-source-abstraction . 参见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. 我的问题是AnnotationConfigApplicationContext使用StandardEnvironment ,它仅在几个地方查找配置文件名称。 Switching to a AnnotationConfigWebApplicationContext made Spring use a StandardServletEnvironment : 切换到AnnotationConfigWebApplicationContext使得Spring使用StandardServletEnvironment

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

Now my webapp environment configuration in conf/Catalina/localhost/foobar.xml works: 现在,我在conf/Catalina/localhost/foobar.xml webapp环境配置可以conf/Catalina/localhost/foobar.xml工作:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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