我只在带有 CDI(焊接)和 JPA(休眠)的 Servlet 容器(Tomcat)中工作。我在网上找到了许多创建“事务”拦截器的示例:
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.interceptor.InterceptorBinding;
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@InterceptorBinding
public @interface Transactional {}
@Transactional
@Interceptor
public class TransactionalInterceptor {
@Inject EntityManager em;
@AroundInvoke
public Object wrapInTransaction(InvocationContext invocation) throws Exception {
boolean transactionOwner = !isTransactionInProgress();
if (transactionOwner) {
em.getTransaction().begin();
}
try {
return invocation.proceed();
}
catch (RuntimeException ex) {
em.getTransaction().setRollbackOnly();
throw ex;
}
finally {
if (transactionOwner) {
if (em.getTransaction().getRollbackOnly()) {
em.getTransaction().rollback();
}
else {
em.getTransaction().commit();
}
}
}
}
private boolean isTransactionInProgress() {
return em.getTransaction().isActive();
}
}
这对我的本地代码很有效。但是,我希望能够将此事务注释(拦截器)应用于我不编写的代码(即我正在使用的库代码)。就我而言,我希望将 CDI 拦截器应用于 Struts2 拦截器,以确保在整个请求处理期间,我会打开一个事务。
如何以这种方式将此事务拦截器应用于库代码?
编辑这是我之前通过 Spring XML 所做的事情:
<!-- TRANSACTIONAL DEMARCATION -->
<aop:config>
<aop:pointcut id="transactionalPointCut" expression="execution(* utils.struts2.interceptor.TransactionInterceptor.intercept(..))"/>
<aop:advisor pointcut-ref="transactionalPointCut" advice-ref="transactionalAdvice"/>
</aop:config>
...
但我正在寻找 CDI 替代方案。