0

In my project with 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>

I have created a custom annotation:

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

and this is mybatis dao:

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

and this is my aspect:

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

and I get parameterNames is null, but i put the annotation on a class's method instead of a interface, i get parameterNames correctly.like this:

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

so, how can i get parameterNames correctly for mybatis dao ? please help me, thanks a lot.

andson
  • 1
  • 2

1 Answers1

0

This one is a classic: You are assuming that just because you made your annotation @Inherited, it will be inherited by implementing classes if you annotate interface methods. But this assumption is wrong. @Inherited only works in exactly one case: when extending an annotated base class. It does not work for annotated interfaces, methods etc. This is also documented here:

Note that this meta-annotation type has no effect if the annotated type is used to annotate anything other than a class. Note also that this meta-annotation only causes annotations to be inherited from superclasses; annotations on implemented interfaces have no effect.

As soon as you annotate your implementing class, it works, which is also what you have described already. Sorry to have no better news, but this is how the Java compiler works.


Update: I forgot to mention that I developed a workaround using AspectJ (not Spring AOP) a while ago. If configured correctly, you can combine AspectJ and Spring AOP in one application.

kriegaex
  • 63,017
  • 15
  • 111
  • 202