搜索

当@within 遇到 继承时


发布时间: 2022-11-24 17:37:00    浏览次数:14 次

背景

项目中用一个注解做切面,拦截的时候,需要获取注解里的值,父类取值是没问题的,但是子类取值是有问题的,具体看一下例子

例子

一个自定义注解
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface MyAnnotation {
    String value() default "me";
}

一个普通的父类
@Slf4j
@MyAnnotation("father")
public class Father {
    public void hello() {}

    public void hello2() {}
}

一个普通的子类
@Slf4j
@MyAnnotation("son")
public class Son extends Father {
    @Override
    public void hello2() {}
}

配置类
@Configuration
@EnableAspectJAutoProxy(exposeProxy = true)
public class Config {

    @Bean
    public Father father() {
        return new Father();
    }

    @Bean
    public Son son() {
        return new Son();
    }
}

切面:
@Slf4j
@Aspect
@Order(-1)
@Component
public class MyAspect {
    @Before("@within(myAnnotation)")
    public void before(JoinPoint point, MyAnnotation myAnnotation) {
        Signature signature = point.getSignature();
        log.info("{}.{}, annotation value:{}",
                signature.getDeclaringType().getSimpleName(), signature.getName(), myAnnotation.value());
    }
}

启动类:
public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context =
                new AnnotationConfigApplicationContext(Config.class, MyAspect.class);
        Father father = context.getBean("father", Father.class);
        father.hello();
        father.hello2();

        Son son = context.getBean(Son.class);
        son.hello();
        son.hello2();
    }
}
输出:

1232 [main] INFO  c.e.l.s.a.annotation.demo.MyAspect - Father.hello, annotation value:father 
1241 [main] INFO  c.e.l.s.a.annotation.demo.MyAspect - Father.hello2, annotation value:father 
1242 [main] INFO  c.e.l.s.a.annotation.demo.MyAspect - Father.hello, annotation value:father 
1248 [main] INFO  c.e.l.s.a.annotation.demo.MyAspect - Son.hello2, annotation value:son 


从结果看出:
访问父类的方法时,获取到的注解的值是没问题的
但是访问子类的方法时,如果没有重写方法,则获取到的注解的值是父类注解值的内容,如果重写了方法,则获取到的是自己类上加的注解的值

解决

如果你不想要重写方法就能获取到自己类上的注解的值,你可以这样做:

新加一个注解
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface MyAnnotation2 {
    String value() default "me2";
}

切面增加以下方法:
    @Before("@within(myAnnotation2)")
    public void before(JoinPoint point, MyAnnotation2 myAnnotation2) {
        Signature signature = point.getSignature();
        MyAnnotation2 annotation = point.getTarget().getClass().getAnnotation(MyAnnotation2.class);
        log.info("--- {}.{}, annotation value:{}",
                signature.getDeclaringType().getSimpleName(), signature.getName(), annotation.value());
    }


父类和子类加上新注解
@Slf4j
@MyAnnotation("father")
@MyAnnotation2("father")
public class Father {}
@Slf4j
@MyAnnotation("son")
@MyAnnotation2("son")
public class Son extends Father {}
再运行一下看一下结果:

1122 [main] INFO  c.e.l.s.a.annotation.demo.MyAspect - Father.hello, annotation value:father 
1127 [main] INFO  c.e.l.s.a.annotation.demo.MyAspect - --- Father.hello, annotation value:father 
1139 [main] INFO  c.e.l.s.a.annotation.demo.MyAspect - Father.hello2, annotation value:father 
1139 [main] INFO  c.e.l.s.a.annotation.demo.MyAspect - --- Father.hello2, annotation value:father 
1141 [main] INFO  c.e.l.s.a.annotation.demo.MyAspect - Father.hello, annotation value:father 
1141 [main] INFO  c.e.l.s.a.annotation.demo.MyAspect - --- Father.hello, annotation value:son 
1147 [main] INFO  c.e.l.s.a.annotation.demo.MyAspect - Son.hello2, annotation value:son 
1147 [main] INFO  c.e.l.s.a.annotation.demo.MyAspect - --- Son.hello2, annotation value:son 

可以看到是想要的结果
免责声明 当@within 遇到 继承时,资源类别:文本, 浏览次数:14 次, 文件大小:-- , 由本站蜘蛛搜索收录2022-11-24 05:37:00。此页面由程序自动采集,只作交流和学习使用,本站不储存任何资源文件,如有侵权内容请联系我们举报删除, 感谢您对本站的支持。 原文链接:https://www.cnblogs.com/eaglelihh/p/16915487.html