我需要为使用嵌入式Tomcat 8应用程序服务器的应用程序设置连接池。通常,我会在context.xml文件中配置一个新资源。但是,当然,使用嵌入式版本时不存在这样的文件。资源的定义如下:
<Context>
<Resource name="jdbc/dbname" auth="Container" type="javax.sql.DataSource" username="username" password="password" driverClassName="org.postgresql.Driver" description="Database" url="jdbc:postgresql://localhost:5432/dbname" maxActive="20" maxIdle="3" />
</Context>
因此,必须有另一种向上下文添加资源的解决方案。是否可以将数据源资源直接添加到代码中的Standardcontext?如果有,怎么样?或者在使用嵌入式版本时如何才能做到这一点?
答案 0 :(得分:1)
您可以编写自己的工厂并将其集成到Tomcat中,然后在Web应用程序的元素中配置此工厂的使用。
您必须编写一个实现JNDI服务提供程序javax.naming.spi.ObjectFactory接口的类。每次Web应用程序在绑定到此工厂的上下文条目上调用lookup()时(假设工厂配置了singleton =“false”),就会调用getObjectInstance()方法。
要创建知道如何生成MyBean实例的资源工厂,您可以创建一个这样的类:
package com.mycompany;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;
public class MyBeanFactory implements ObjectFactory {
public Object getObjectInstance(Object obj,
Name name2, Context nameCtx, Hashtable environment)
throws NamingException {
// Acquire an instance of our specified bean class
MyBean bean = new MyBean();
// Customize the bean properties from our attributes
Reference ref = (Reference) obj;
Enumeration addrs = ref.getAll();
while (addrs.hasMoreElements()) {
RefAddr addr = (RefAddr) addrs.nextElement();
String name = addr.getType();
String value = (String) addr.getContent();
if (name.equals("foo")) {
bean.setFoo(value);
} else if (name.equals("bar")) {
try {
bean.setBar(Integer.parseInt(value));
} catch (NumberFormatException e) {
throw new NamingException("Invalid 'bar' value " + value);
}
}
}
// Return the customized instance
return (bean);
}
}
在此示例中,我们无条件地创建com.mycompany.MyBean类的新实例,并根据配置此工厂的元素中包含的参数填充其属性(请参见下文)。您应该注意,应该跳过任何名为factory的参数 - 该参数用于指定工厂类本身的名称(在本例中为com.mycompany.MyBeanFactory),而不是正在配置的bean的属性。
接下来,修改Web应用程序部署描述符(/WEB-INF/web.xml)以声明JNDI名称,在该名称下将请求此Bean的新实例。最简单的方法是使用一个元素,如下所示:
<resource-env-ref>
<description>
Object factory for MyBean instances.
</description>
<resource-env-ref-name>
bean/MyBeanFactory
</resource-env-ref-name>
<resource-env-ref-type>
com.mycompany.MyBean
</resource-env-ref-type>
</resource-env-ref>
警告 - 请务必遵守所需的元素排序 Web应用程序部署描述符的DTD!请参阅Servlet 详细规范。
此资源环境引用的典型用法可能如下所示:
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
MyBean bean = (MyBean) envCtx.lookup("bean/MyBeanFactory");
writer.println("foo = " + bean.getFoo() + ", bar = " +
bean.getBar());
要配置Tomcat的资源工厂,请将此类元素添加到此Web应用程序的元素中。
<Context ...>
...
<Resource name="bean/MyBeanFactory" auth="Container"
type="com.mycompany.MyBean"
factory="com.mycompany.MyBeanFactory"
singleton="false"
bar="23"/>
...
</Context>
答案 1 :(得分:0)
问题是关于嵌入式tomcat的。