多年来,我一直在使用 Tomcat 6.0.26-6.0.35 和 JSF 2 Mojarra,各种版本一直到 2.1.2,我已经使用了几个月。我有几个请求范围和 session 范围的 bean,代码如下:
private @Resource(name="jdbc/cLabs", mappedName="jdbc/cLabs") DataSource cLabs;
它已正确注入(inject)我使用的每个版本的 Tomcat 6 中。我还有其他类型的 @Resource
也不起作用,所以它不仅仅是 DataSource 资源。
我试过切换到 Tomcat 7.0.27 并突然这些结构都不再起作用了。资源未注入(inject)。我还有其他类型的 @Resource
也不起作用,所以它不仅仅是 DataSource
资源。然而,在每种情况下,命名的资源确实存在,并且可以通过例如
new InitialContext().lookup("java:comp/env/jdbc/cLabs");
[它们由 context.xml 中的元素定义]
这当然是皇家 PITA,因为我在一两年前花了一些时间用前者替换了后者。我是否需要对 Tomcat 7 编织一些其他魔法才能使其再次运行?
请注意,资源被正确地注入(inject)到 Servlet 中,因此它并没有完全损坏。 Tomcat 和 JSF 之间的一些交互。
最佳答案
我的猜测是某些原因导致 org.apache.catalina.core.DefaultInstanceManager 忽略注释,因为面部需要 @PostConstruct 方法来处理 @Resource 字段。我创建了一个解决方法,适用于使用 @Resource 注释的字段。
将以下内容添加到 web.xml 中:
<context-param>
<param-name>com.sun.faces.injectionProvider</param-name>
<param-value>com.example.faces.Tomcat7InjectionProvider</param-value>
</context-param>
并将该类添加到您的源中:
package com.example.faces;
import java.lang.reflect.Field;
import javax.annotation.Resource;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.ServletContext;
import org.apache.catalina.util.Introspection;
import com.sun.faces.spi.InjectionProviderException;
import com.sun.faces.vendor.WebContainerInjectionProvider;
public class Tomcat7InjectionProvider extends WebContainerInjectionProvider {
public Tomcat7InjectionProvider(ServletContext servletContext) {
}
@Override
public void inject(Object managedBean) throws InjectionProviderException {
if (managedBean != null) {
// see org.apache.catalina.core.DefaultInstanceManager
Field[] fields = Introspection.getDeclaredFields(managedBean.getClass());
for (Field field : fields) {
// field may be private
field.setAccessible(true);
if (field.isAnnotationPresent(Resource.class)) {
Resource annotation = null;
try {
annotation = field.getAnnotation(Resource.class);
Context ctx = new InitialContext();
Object resource = ctx.lookup("java:comp/env/" + annotation.name());
field.set(managedBean, resource);
} catch (Exception e) {
throw new InjectionProviderException("cannot find resource " + annotation.name(), e);
}
}
}
}
}
}
关于jsf - Tomcat @Resource 注释 API 注释在 Tomcat 7 中停止工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10814557/