我正在使用Tomcat9部署共享相同数据源连接池的多个应用程序。我通过以下方式达到了目的:
它正在按预期方式工作。
但是我有一个要求避免编辑任何xml(server.xml或conf / context.xml或应用程序特定的context.xml),并尝试以编程方式实现步骤1和2。如果是这样,好处是,只需修改需要添加到/ lib中的jar即可支持新的数据源,而无需对任何xml进行任何修改(或者可以在server.xml中进行最小配置)。
是否有任何方法可以满足将资源定义为GlobalNamingResources并将其通过ResourceLink(全部通过Java链接到Web应用程序)的要求?
经过tomcat javadocs后,我已经达到了我的要求。下面给出详细信息:
1。将数据源添加为GlobalNamingResource
为此,创建服务器生命周期侦听器,创建数据源并将其添加到JNDI GlobalNamingContext。
public class GlobalDatasourceCreator implements LifecycleListener {
@Override
public void lifecycleEvent(LifecycleEvent event) {
if (event.getSource() instanceof Server) {
Context namingContext = ((Server) event.getSource()).getGlobalNamingContext();
if (Lifecycle.START_EVENT.equals(event.getType())) {
bindDatasources(namingContext);
} else if (Lifecycle.STOP_EVENT.equals(event.getType())) {
unbindDatasources(namingContext);
}
}
}
private void bindDatasources(Context namingContext) {
if (createSubContext(namingContext)) {
try {
DataSource ds = getDatasource(); //TODO: Implement it
namingContext.rebind("jdbc/myds_global", ds);
} catch (Exception e) {
e.printStackTrace();
}
}
}
private boolean createSubContext(Context namingContext) {
try {
namingContext.createSubcontext("jdbc");
} catch (NameAlreadyBoundException e) {
} catch (NamingException e) {
return false;
}
return true;
}
private void unbindDatasources(Context namingContext) {
try {
namingContext.unbind("jdbc/myds_global");
} catch (NamingException e) {
e.printStackTrace();
}
}
然后将此类作为侦听器添加到conf / server.xml中>]
<Listener className="com.oracle.acs.gateway.ds.GlobalDatasourceCreator" />
2。通过ResourceLink将数据源公开给所有Web应用程序
创建上下文LifecycleListener。在START事件上,创建ResourceLink并将其附加到上下文。
注意:由于这是上下文级别的侦听器,因此将为所有应用程序创建ResourceLink。我的要求是将其公开给所有应用程序,因为它是受控环境。如果仅需要为选定的应用程序创建ResourceLink,则可以应用基于上下文名称的过滤。
中>]public class AppDatasourceLinkCreator implements LifecycleListener { @Override public void lifecycleEvent(LifecycleEvent event) { if (event.getSource() instanceof Context) { Context ctx = (Context) event.getSource(); if (Lifecycle.START_EVENT.equals(event.getType())) { addResourceLink(ctx); } else if (Lifecycle.STOP_EVENT.equals(event.getType())) { removeResourceLink(ctx); } } } private void removeResourceLink(Context ctx) { ctx.getNamingResources().removeResourceLink("jdbc/myds"); } private void addResourceLink(Context ctx) { ContextResourceLink resourceLink = new ContextResourceLink(); resourceLink.setGlobal("jdbc/myds_global"); resourceLink.setName("jdbc/myds"); resourceLink.setType("javax.sql.DataSource"); ctx.getNamingResources().addResourceLink(resourceLink); } }
然后将此类作为侦听器添加到conf / context.xml
不需要进一步的xml修改即可添加任何数量的数据源。只需修改Java代码以添加新的数据源,更新lib文件夹中的jar并重新启动服务器,即可完全满足我的项目要求。这也解决了将数据源凭据以xml的纯文本格式公开的问题(尽管不是100%的风险证明)。<Listener className="com.oracle.acs.gateway.ds.AppDatasourceLinkCreator" />
创建包含这两个类的jar并将其放置在/ lib文件夹中。
Advantage: