• Spring注解编程 之 注解合并


    注解编程 之 注解合并

    组合注解

    Spring4.2之后,就提供了组合注解的实现方式,就是将多个注解作用于一个注解,用一个注解就和依赖实现多个注解的功能。是作用的注解元素看上去更简洁美观,更强大之处是属性覆盖功能。

    例如:Spring@RestController,它将@ResponseBody@Controller两个注解组合为一个,那么在Controller类上只需加上@RestController即可实现加两个注解才能实现的功能。

     
     
     
    x
     
     
     
     
    1
    @Target(ElementType.TYPE)
    2
    @Retention(RetentionPolicy.RUNTIME)
    3
    @Documented
    4
    @Controller  //组合Controller使其实现Bean注册
    5
    @ResponseBody  //组合ResponseBody使其支持将结果转化为json
    6
    public @interface RestController {
    7
    
    
    8
        /**
    9
         * The value may indicate a suggestion for a logical component name,
    10
         * to be turned into a Spring bean in case of an autodetected component.
    11
         * @return the suggested component name, if any (or empty String otherwise)
    12
         * @since 4.0.1
    13
         */
    14
        @AliasFor(annotation = Controller.class)
    15
        String value() default "";
    16
    }
     
     

    自定义注解

     
     
     
    x
     
     
     
     
    1
    public class SelfAnnotationTest {
    2
        @Target({ ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.TYPE })
    3
        @Retention(RetentionPolicy.RUNTIME)
    4
        @interface TestOne {
    5
            String testOne() default "testOne";
    6
        }
    7
    8
        @Target({ ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.TYPE })
    9
        @Retention(RetentionPolicy.RUNTIME)
    10
        @interface TestTwo {
    11
            String testTwo() default "testTwo";
    12
        }
    13
    14
        @TestTwo
    15
        @Target({ ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.TYPE })
    16
        @Retention(RetentionPolicy.RUNTIME)
    17
        @interface TestThree {
    18
            String testThree() default "testThree";
    19
        }
    20
    21
        @TestThree
    22
        static class Element {}
    23
    24
        public static void main(String[] args) {
    25
            TestTwo testTwo = AnnotatedElementUtils.getMergedAnnotation(Element.class, TestTwo.class);
    26
            TestThree testThree = AnnotatedElementUtils.getMergedAnnotation(Element.class, TestThree.class);
    27
            System.out.println(testTwo);
    28
            System.out.println(testThree);
    29
        }
    30
    }
     
     

    输出:

     
     
     
    x
     
     
     
     
    1
    @com.example.helloworld.annotation.SelfAnnotationTest$TestTwo(testTwo=testTwo)
    2
    @com.example.helloworld.annotation.SelfAnnotationTest$TestThree(testThree=testThree)
    3
    4
    Process finished with exit code 0
     
     

    可以看出,AnnotatedElemnetUtils.getMergedAnnotation()方法可以返回组合注解本身,及此注解上的元注解。

    自定义注解合并

     
     
     
    xxxxxxxxxx
    1
    21
     
     
     
     
    1
        @TestOne
    2
        @TestTwo
    3
        @Target({ ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.TYPE })
    4
        @Retention(RetentionPolicy.RUNTIME)
    5
        @interface TestThree { // 合并 @TestOne 及 @TestTwo 注解
    6
            String testThree() default "testThree";
    7
            String testTwo();  // 自动对应 @TestTwo 中的属性
    8
            String testOne();  // 自动对应 @TestOne 中的属性
    9
        }
    10
    11
        @TestThree(testTwo = "test2", testOne = "test1")
    12
        static class Element {}
    13
    14
        public static void main(String[] args) {
    15
            TestTwo testTwo = AnnotatedElementUtils.getMergedAnnotation(Element.class, TestTwo.class);
    16
            System.out.println(testTwo.testTwo());
    17
            TestThree testThree = AnnotatedElementUtils.getMergedAnnotation(Element.class, TestThree.class);
    18
            System.out.println(testThree.testThree());
    19
            TestOne testOne = AnnotatedElementUtils.getMergedAnnotation(Element.class, TestOne.class);
    20
            System.out.println(testOne.testOne());
    21
        }
     
     

    输出:

     
     
     
    xxxxxxxxxx
    1
     
     
     
     
    1
    test2
    2
    testThree
    3
    test1
    4
    5
    Process finished with exit code 0
     
     

    组合注解实现属性值覆盖

    Spring组合注解中的属性覆盖功能,即更底层的注解属性方法覆盖高层次注解的属性方法。实现该功能需要Spring提供的另外一个注解@AliasFor配合完成。

     
     
     
    x
     
     
     
     
    1
    public class SelfAnnotationTest {
    2
        @Target({ ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.TYPE })
    3
        @Retention(RetentionPolicy.RUNTIME)
    4
        @interface TestOne {
    5
            String testOne1() default "testOne";
    6
        }
    7
    8
        @Target({ ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.TYPE })
    9
        @Retention(RetentionPolicy.RUNTIME)
    10
        @TestOne
    11
        @interface TestTwo {
    12
            String testTwo2() default "testTwo";
    13
        }
    14
    15
        @Target({ ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.TYPE })
    16
        @Retention(RetentionPolicy.RUNTIME)
    17
        @TestTwo
    18
        @interface TestThree {
    19
            @AliasFor(annotation = TestTwo.class, attribute = "testTwo2")
    20
            String testThree() default "testThree";
    21
            @AliasFor(annotation = TestOne.class, attribute = "testOne1")
    22
            String testThree2() default "testThree2";
    23
    24
        }
    25
    26
        @TestThree(testThree = "testThree 覆盖了 testTwo2", testThree2 = "testThree2 覆盖了 testOne1")
    27
        static class Element {}
    28
    29
        public static void main(String[] args) {
    30
            TestTwo testTwo = AnnotatedElementUtils.getMergedAnnotation(Element.class, TestTwo.class);
    31
            System.out.println(testTwo.testTwo2());
    32
            TestOne testOne = AnnotatedElementUtils.getMergedAnnotation(Element.class, TestOne.class);
    33
            System.out.println(testOne.testOne1());
    34
        }
    35
    }
     
     

    输出:

     
     
     
    x
     
     
     
     
    1
    testThree 覆盖了 testTwo2
    2
    testThree2 覆盖了 testOne1
    3
    4
    Process finished with exit code 0
     
     

    以上为三层属性覆盖,支持无限层覆盖。

    Windy心梦无痕
  • 相关阅读:
    SSM中shiro的基本使用
    TortoiseGit小乌龟 git管理工具
    vux用法
    vue webpack打包
    vue2.0 watch
    vue2.0 $emit $on组件通信
    简单工具 & 杂技
    html基础问题总结
    Node应用进程管理器pm2的使用
    node express 登录拦截器 request接口请求
  • 原文地址:https://www.cnblogs.com/windy-xmwh/p/14716234.html
Copyright © 2020-2023  润新知