拦截在Java EE 7上使用CDI的AOP进行日志记录的异常

时间:2015-05-15 16:07:45

标签: exception logging cdi aop java-ee-7

我有以下类片段,我想从中移除重复的日志代码并使用CDI的AOP将其移动到Interceptor。

/**
 * Javadoc omitted
 */
public abstract class JpaDao<T extends LongIdentifiable> implements
        GenericDao<T> { 

    @Override
    @Transactional
    public Long persist(T type) throws GeneralPersistenceException {
        if (type == null) {
            throw new GeneralPersistenceException("Can't persist null");
        }

        try {
            entityManager.persist(type);
            return type.getId();
        } catch (PersistenceException e) {
            String message = "Failed to persist an entity";
            logger.error(message, e);
            throw new GeneralPersistenceException(message, e);
        }

    }

    @Override
    @Transactional
    public T merge(T type) throws GeneralPersistenceException {
        if (type == null) {
            throw new GeneralPersistenceException("Can't merge null");
        }

        try {
            T mergedType = entityManager.merge(type);
            return mergedType;
        } catch (PersistenceException e) {
            String message = "Failed to merge an entity";
            logger.error(message, e);
            throw new GeneralPersistenceException(message, e);
        }
    }
}

请注意下面的代码段,该代码段在persist e merge方法中重复

} catch (PersistenceException e) {
    String message = "Failed to persist an entity";
    logger.error(message, e);
    throw new GeneralPersistenceException(message, e);
}

替换上述代码段的候选代码如下:

} catch (PersistenceException e) {
    throw new GeneralPersistenceException("Failed to persist an entity", e);
}

换句话说,我希望每次抛出GeneralPersistenceException时,都会写一条日志消息。我的例外情况如下:

public class GeneralPersistenceException extends Exception {
    private static final long serialVersionUID = -6057737927996676949L;

    public GeneralPersistenceException() {
    }

    public GeneralPersistenceException(String message) {
        super(message);
    }

    public GeneralPersistenceException(String message, Throwable cause) {
        super(message, cause);
    }

    public GeneralPersistenceException(Throwable cause) {
        super(cause);
    }
}

正如您所看到的,Exception只有构造函数。 鉴于这种情况,我有以下问题:

  1. 在符合Java EE 7的应用程序中解决此问题的最佳策略是将AOP与CDI结合使用?
  2. 如果是AOP,我应该截取GeneralPersistenceException吗?
  3. 是否可以拦截GeneralPersistenceException的构造函数,或仅拦截方法(尚不存在)?
  4. 是否已经为此目的实施了一些东西,我正在重新发明轮子?
  5. 提前致谢。

1 个答案:

答案 0 :(得分:1)

您不能拦截异常,因为它是使用** new *创建的,并且它不会由CDI管理。在实践中,你不应该以这种方式拦截。 您正在寻找的解决方案是拦截您服务中的呼叫,在那里捕获您的异常并记录它。