java - AspectJ 匹配带注释的类,但不匹配其子类

标签 java annotations aop aspectj

我想在我的 DAO 父类上配置事务并禁止具体的 DAO 有自己的事务配置,所以我使用 Springs @Transactional:

@Transactional(/* some transactionConfig */)
abstract class AbstractDao
{
    //...
}

// this is ok
class UserDao extends AbstractDao
{
    //...
}

@Transactional (/* some other config*/) // this should be illegal
class DocumentDao extends AbstractDao
{
    //...
}

我使用 AspectJs @DeclareError 来强制执行我的设计规则。当我使用 followint 错误和切入点声明时,(合法)UserDao 中的代码也会出现错误,因为它继承了 AbstractDao 的注释。

@Pointcut("call(*.new(..)) || call(* *(..)) || set (* *) || get (* *)")
public void doAnything()
{
    // no code
}

@Pointcut("within(@org.springframework.transaction.annotation.Transactional *) && doAnything()")
public void transactionalClass()
{
    // only pointcut, no code
}

@Pointcut("within(AbstractDao+) && !within(AbstractDao)")
public void inDao()
{
    // no code
}

@DeclareError("transactionalMethod() && doAnything() && inDao()")
public static final String TRANSACTIONAL_NOT_ALLOWED =
        "@Transactional of this method is not necesarry, we have it on class level in AbstractDao";

@DeclareError("transactionalClass() && inDao() && doAnything()")
public static final String ERROR = "Transactional is not allowed on method level";

是否可以仅匹配显式注释的类(在本例中为 DocumentDao)?

最佳答案

所以,我认为您正在寻求捕获 @Transactional 在 AbstractDao 子类中的方法或类上的使用。假设是这种情况,以下内容应该有效:

@Pointcut("within(AbstractDao+) && !within(AbstractDao)")
public void inDao()
{
    // no code
}

@Pointcut("within(@org.springframework.transaction.annotation.Transactional *)")
public void transactionalClass()
{
    // no code
}

@Pointcut("withinCode(@org.springframework.transaction.annotation.Transactional *.*(..))")
public void transactionalMethod()
{
    // no code
}

@DeclareError("(transactionalMethod() || transactionalClass()) && inDao()")
public static final String TRANSACTIONAL_NOT_ALLOWED = "NOT ALLOWED!";

我实际上还没有尝试过这一点,因此您可能需要对切入点进行一些调整,但这应该是可行的。

<小时/>

编辑:更简洁的答案是:

pointcut transactionsNotAllowed() : (within(@Transactional AbstractDao+) || 
  execution(@Transactional * AbstractDao+.*(..))) && !within(AbstractDao);

这应该适合你。它使用代码风格的aspectj语法,我发现它更直观。

关于java - AspectJ 匹配带注释的类,但不匹配其子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24866791/

相关文章:

java - 替换字符串中的括号

java - Swing Scala 问题 - 面板 100% 扩展

java - 为什么 getAnnotatedParameterTypes 看不到数组类型的注释?

java - 如何向 JUNIT 测试套件添加方法..?

mono - 有人在 Mono 下使用过任何 AOP 产品吗?

java - 没有 Spring 的 Jersey 和 AOP

Java OpenGL 混合图像颜色

java - 使用 hibernate 注解映射 @ManyToMany 关系

java - Spring aop 拦截来自同一服务类的调用

java - 为什么我的 play 框架构建有时会获取 oss-parent 依赖项?