在mybatis dao的方法上具有自定义注释的spring aop,parameterNames为null

时间:2019-07-05 02:46:43

标签: annotations mybatis dao spring-aop

在我的带有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岛:

@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();
    }
}

,我得到parameterNames为空, 但是我将注释放在类的方法而不是接口上,我可以正确获取parameterNames。像这样:

@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的parameterNames? 请帮助我,非常感谢。

1 个答案:

答案 0 :(得分:0)

这是经典之作:您假设仅仅是因为您进行了注释@Inherited,如果您对接口方法进行注释,则实现类将继承它。但是这个假设是错误的。 @Inherited仅在以下一种情况下有效:扩展带注释的基类时。它不适用于带注释的接口,方法等。这也记录在here中:

  

请注意,如果注释类型用于注释除类之外的任何内容,则此元注释类型无效。还要注意,此元注释仅使注释从超类继承;已实现的接口上的注释无效。

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


更新:我忘了提到我前一段时间开发了workaround using AspectJ(不是Spring AOP)。如果配置正确,则可以在一个应用程序中组合AspectJ和Spring AOP。