我喜欢.properties
文件而不是
- JNDI - 为什么在程序配置而不是初始化时构建复杂对象?
- 系统属性 - 您不能在单个 Tomcat 中单独配置相同 WAR 的多个实例
- 上下文参数 - 它们只能在 中访问
javax.servlet.Filter
,javax.servlet.ServletContextListener
这很不方便
Tomcat 7 Context包含 Loader元素。根据文档部署描述符(<Context>
标签中的内容)可以放在:
$CATALINA_BASE/conf/server.xml
- 坏 - 需要重新启动服务器才能重新读取配置
$CATALINA_BASE/conf/context.xml
- 不好 - 在所有应用程序中共享
$CATALINA_BASE/work/$APP.war:/META-INF/context.xml
- 不好 - 需要重新打包才能更改配置
$CATALINA_BASE/work/[enginename]/[hostname]/$APP/META-INF/context.xml
-不错,但请看最后一个选项!!
$CATALINA_BASE/webapps/$APP/META-INF/context.xml
-不错,但请看最后一个选项!!
$CATALINA_BASE/conf/[enginename]/[hostname]/$APP.xml
-最好- 完全退出应用程序并自动扫描更改!!!
Context
可以保存自定义Loader
org.apache.catalina.loader.VirtualWebappLoader(在现代 Tomcat 7 中可用,您可以将自己的单独的类路径添加到您的.properties
),和Parameter
(通过访问FilterConfig.getServletContext().getInitParameter(name)
)和Environment
(通过访问new InitialContext().lookup("java:comp/env").lookup("name")
):
<Context docBase="${basedir}/src/main/webapp"
reloadable="true">
<!-- http://tomcat.apache.org/tomcat-7.0-doc/config/context.html -->
<Resources className="org.apache.naming.resources.VirtualDirContext"
extraResourcePaths="/WEB-INF/classes=${basedir}/target/classes,/WEB-INF/lib=${basedir}/target/${project.build.finalName}/WEB-INF/lib"/>
<Loader className="org.apache.catalina.loader.VirtualWebappLoader"
virtualClasspath="${basedir}/target/classes;${basedir}/target/${project.build.finalName}/WEB-INF/lib"/>
<JarScanner scanAllDirectories="true"/>
<Parameter name="min" value="dev"/>
<Environment name="app.devel.ldap" value="USER" type="java.lang.String" override="true"/>
<Environment name="app.devel.permitAll" value="true" type="java.lang.String" override="true"/>
</Context>
如果您使用 Spring 并且它是 XML 配置:
<context:property-placeholder location="classpath:app.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@${db.host}:${db.port}:${db.user}"/>
<property name="username" value="${db.user}"/>
<property name="password" value="${db.pass}"/>
</bean>
使用 Spring 将上述属性注入 bean 字段很容易:
@Value("${db.user}") String defaultSchema;
而不是 JNDI:
@Inject ApplicationContext context;
Enviroment env = context.getEnvironment();
String defaultSchema = env.getProperty("db.user");
另请注意,EL 允许这样做(默认值和深度递归替换):
@Value('${db.user:testdb}') private String dbUserName;
<property name='username' value='${db.user.${env}}'/>
也可以看看:
注意通过将类路径扩展到实时目录,您还允许外部化任何其他配置,例如日志记录、身份验证、atc。我logback.xml
以这种方式外化。
更新 Tomcat 8 更改 <Resources>
和<Loader>
元素的语法,对应的部分现在看起来像:
<Resources>
<PostResources className="org.apache.catalina.webresources.DirResourceSet"
webAppMount="/WEB-INF/classes" base="${basedir}/target/classes" />
<PostResources className="org.apache.catalina.webresources.DirResourceSet"
webAppMount="/WEB-INF/lib" base="${basedir}/target/${project.build.finalName}/WEB-INF/lib" />
</Resources>