3

我只在带有 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 替代方案。

4

1 回答 1

2

这在 CDI 1.0 中变得很困难。您必须打开 jar 并在 META-INF 中添加 beans.xml,重新打包 jar 并在您的战争(我假设这是一场战争)中创建一个可移植扩展以将元数据拦截器注释添加到类中。您需要观察 BeforeBeanDiscovery并添加一个新的AnnotatedType. DeltaSpike 可以在这部分提供帮助。

于 2013-05-14T14:26:46.513 回答