Spring AOP 带有对 mybatis DAO 方法的自定义注释,参数名称为空



在我的项目中,带有Spring Boot 2.1.3.Release,

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>

我创建了一个自定义注释:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MyAnnotation {
}

这是mybatis dao:

@Component
@Mapper
public interface MyOrderDao {
    @MyAnnotation
    List<MyOrder> findBySerialNo(String orderNo);
}

这是我的方面:

@Aspect
@Component
public class MyAspect {
    @Pointcut(value = "@annotation(MyAnnotation)")
    public void pointCut() {
    }
    @Around("pointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        String [] parameterNames = methodSignature.getParameterNames();
        // TODO
        return joinPoint.proceed();
    }
}

我得到的参数是null,但是我将注释放在班级的方法上而不是接口上,我正确地获得了参数。例如:

@Service
public class MyOrderService {
    @Autowired
    private MyOrderDao myOrderDao;
    @MyAnnotation
    public MyOrder getOrderBySerialNo(String serialNo) {
        if (StringUtils.isBlank(serialNo)) {
            return null;
        }
        List<MyOrder> orders = myOrderDao.findBySerialNo(serialNo);
        if (orders != null && !orders.isEmpty()) {
            return orders.get(0);
        }
        return null;
    }
}

那么,如何正确获取Mybatis Dao的参数?请帮助我,非常感谢。

这是一个经典:您假设仅是因为您对注释@Inherited进行了注释,它将通过实现类接口方法来继承。但是这个假设是错误的。@Inherited仅在一种情况下工作:扩展带注释的基类时。它不适用于注释的接口,方法等。此处也记录在这里:

请注意,如果使用带注释的类型来注释类,则这种元监管类型没有效果。还要注意,这种元宣传仅导致注释是从超类的继承的。实施接口的注释没有效果。

一旦您注释实现类,它就可以起作用,这也是您已经描述的。很抱歉没有更好的消息,但这就是Java编译器的工作方式。


更新:我忘了提到我在一段时间前使用FacteactJ(而不是Spring AOP(开发了解决方法。如果配置正确,则可以将AppackJ和Spring AOP组合在一个应用程序中。

最新更新