【发布时间】:2014-01-10 08:34:42
【问题描述】:
背景
我正在开发一个 Web 应用程序,我尝试在其中集成 Vaadin 和 DB4O 以及在 TomEE 容器中运行的 CDI。为了拥有数据库事务,我创建了 ServletFilter,它拦截所有请求并在请求结束时提交或回滚。
@WebFilter("/*")
public class DBTransactionHandler implements Filter {
@Inject
SessionImpl sessionImpl;
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException {
boolean hadException = false;
try {
chain.doFilter(request, response);
} catch (RuntimeException ex) {
hadException = true;
throw ex;
} finally {
if (sessionImpl != null) {
if (hadException || sessionImpl.isRollbackOnly()) {
sessionImpl.rollback();
} else {
sessionImpl.commit();
}
sessionImpl.close();
}
}
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
我有一个设置为@RequestScoped 的SessionImpl。有了这个,我试图实现在处理 HTTP 请求时需要使用数据库的所有服务,然后它们应该获得相同的实例,因此它将在相同的数据库事务中执行。
/**
* http://community.versant.com/documentation/reference/db4o-8.0/java/reference/Content/platform_specific_issues/web/servlets.htm
*/
@RequestScoped
public class SessionImpl implements Session {
@Inject
DBConnectionFactory connectionFactory;
private boolean rollbackOnly;
private ObjectContainer delegate;
@PostConstruct
public void init() {
delegate = connectionFactory.getConnection().ext().openSession();
}
//.... many other database related methods
}
我的所有服务都来自AbstractService,因此他们立即进行了工作会话。
public class AbstractService {
@Inject
protected BeanManager beanManager;
@Inject
protected Session db;
}
这就是我目前所拥有的,我的问题来了:
问题
在我的 Web 应用程序中,我需要创建一个 Scheduler 组件。预定的作业将使用我已经拥有的相同服务。由于SessionImpl 是@RequestScoped 并且我在计划的作业中没有HTTP 请求,因此无法注入SessionImpl。
- 我能否以某种方式从调度程序线程激活 RequestScope 上下文?
我试图做的是创建一个自定义范围@SchedulerScoped。这将在调度程序开始执行作业之前激活。这种方法的问题在于,当我向SessionImpl 添加第二个范围时,我的应用程序不再部署:
SEVERE: CDI Beans module deployment failed
org.apache.webbeans.exception.WebBeansConfigurationException: Managed Bean implementation class : org.reluxa.db.SessionImplstereotypes must declare the same @Scope annotations.
at org.apache.webbeans.config.DefinitionUtil.defineScopeType(DefinitionUtil.java:390)
at org.apache.webbeans.component.creation.AbstractBeanCreator.defineScopeType(AbstractBeanCreator.java:145)
at org.apache.webbeans.util.WebBeansUtil.defineManagedBean(WebBeansUtil.java:2548)
at org.apache.openejb.cdi.BeansDeployer.defineManagedBean(BeansDeployer.java:552)
at org.apache.openejb.cdi.OpenEJBLifecycle.deployManagedBeans(OpenEJBLifecycle.java:407)
【问题讨论】: