假设您有一个tomcat / conf / context.xml文件,如下所示:
WEB-INF/web.xml
name="jdbc/MyDB"
auth="Container"
type="javax.sql.DataSource"
removeAbandoned="true"
removeAbandonedTimeout="15"
maxActive="5"
maxIdle="5"
maxWait="7000"
username="${db.mydb.uid}"
password="${db.mydb.pwd}"
driverClassName="${db.mydb.driver}"
url="${db.mydb.url}${db.mydb.dbName}?autoReconnectForPools=true&characterEncoding=UTF-8"
factory="com.mycompany.util.configuration.CustomDataSourceFactory"
validationQuery="SELECT '1';"
testOnBorrow="true"/>
在这种情况下我们想要替换的是此资源定义中${.*}内容中的任何内容.但是,稍微修改下面的代码,您可以在几乎任何您想要的标准上执行这些替换.
注意line factory =“com.mycompany.util.configuration.CustomDataSourceFactory”
这意味着Tomcat将尝试使用此工厂来处理此资源.应该提到的是,这意味着这个工厂必须在启动时在Tomcat的类路径上(就我个人而言,我将它放在Tomcat lib目录中的JAR中).
这是我工厂的样子:
package com.mycompany.util.configuration;
import java.util.Hashtable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import javax.naming.spi.ObjectFactory;
import org.apache.commons.dbcp.BasicDataSourceFactory;
public class CustomDataSourceFactory extends BasicDataSourceFactory implements ObjectFactory {
private static final Pattern _propRefPattern = Pattern.compile("\\$\\{.*?\\}");
//http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html#Adding_Custom_Resource_Factories
@Override
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception {
if (obj instanceof Reference) {
Reference ref = (Reference) obj;
System.out.println("Resolving context reference values dynamically");
for(int i = 0; i RefAddr addr = ref.get(i);
String tag = addr.getType();
String value = (String) addr.getContent();
Matcher matcher = _propRefPattern.matcher(value);
if (matcher.find()) {
String resolvedValue = resolve(value);
System.out.println("Resolved " + value + " to " + resolvedValue);
ref.remove(i);
ref.add(i, new StringRefAddr(tag, resolvedValue));
}
}
}
// Return the customized instance
return super.getObjectInstance(obj, name, nameCtx, environment);
}
private String resolve(String value) {
//Given the placeholder, do stuff to figure out what it's true value should be, and return that String.
//This could be decryption, or maybe using a properties file.
}
}
然后,一旦此代码在类路径上,重新启动Tomcat并观察catalina.out以获取日志消息.注意:System.out.println语句可能最终会将敏感信息打印到您的日志中,因此您可能希望在完成调试后删除它们.
在旁注中,我写了这个,因为我发现许多例子对于一个特定主题(例如利用密码学)来说太具体了,我想说明如何一般地完成这个.此外,这个问题的其他一些答案并没有很好地解释自己,我不得不做一些挖掘来弄清楚需要做些什么来使这项工作.我想和你们分享我的发现.如果您发现问题,请随时对此发表评论,提出任何问题或进行更正,我将确保将修复内容添加到我的答案中.