• @AliasFor注解详解(结合源码分析)


    一. 概述

    网上关于该注解的描述大都抄来抄去,没有涉及到最本质的源码问题, 下面是笔者结合注解源码, 以及其他常用的注解源码, 来分析@AliasFor注解的主要功能以及展示实际使用场景


    描述:@AliasFor是一个注解,用于声明注解属性的别名。它有两种不同的应用场景。

    • 同一个注解中的两个属性, 互为别名(功能相同)
    • 帮助某个属性继承其他注解的功能

    二. 功能

    1. 同一个注解中的两个属性, 互为别名(功能相同)

    我们先来看一下@AliasFor的源码

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD})
    @Documented
    public @interface AliasFor {
        @AliasFor("attribute")
        String value() default "";
    
        @AliasFor("value")
        String attribute() default "";
    
        Class<? extends Annotation> annotation() default Annotation.class;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    @AliasFor源码本身就用到了第一个特点,即:@AliasFor(value=“xxx”)等价@AliasFor(attribute=“xxx”)

    下面是一个@AliasFor注解在请求映射注解@RequestMapping中的实际应用, 看一下@RequestMapping注解的源码:

    @Target({ElementType.METHOD, ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Mapping
    public @interface RequestMapping {
     
    	String name() default "";
    	
    	@AliasFor("path")
    	String[] value() default {};
     
    	@AliasFor("value")
    	String[] path() default {};
    
    	RequestMethod[] method() default {};
    	String[] params() default {};
    	String[] headers() default {};
    	String[] consumes() default {};
    	String[] produces() default {};
     
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    可以看到,按照@AliasFor注解的第一个特点,@RequestMapping(path=(xxx))等价于@RequestMapping(value=(xxx)),想一想我们实际应用中是不是也是这样~

    2. 帮助某个属性继承其他注解的功能

    说白了, 就是某个注解内的属性, 功能复制了其他的注解, 比如我们很熟悉的@Service@Component等价, 原因就是@Serivce注解内部定义了@AliasFor
    @Serivce源码如下:

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Component
    public @interface Service {
     
    	@AliasFor(annotation = Component.class)
    	String value() default "";
     
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    可以看到,@Servicevalue值, 即为@Component,也就是说,@Service(value = "xxx")等价于@Component(value = "xxx"), 进一步推导出,@Service@Component等价。

    同理,@Component、@Repository、@Service、@Controller四个注解相互等价


    以上就是关于@AliasFor的两个性质, 下面我分析了@SpringBootApplication注解的源码, 有兴趣的同学可以看下。

    三. 分析@SpringBootApplication注解源码

    源码如下:

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan(
        excludeFilters = {@Filter(
        type = FilterType.CUSTOM,
        classes = {TypeExcludeFilter.class}
    ), @Filter(
        type = FilterType.CUSTOM,
        classes = {AutoConfigurationExcludeFilter.class}
    )}
    )
    public @interface SpringBootApplication {
        @AliasFor(
            annotation = EnableAutoConfiguration.class,
            attribute = "exclude"
        )
        Class<?>[] exclude() default {};
    
        @AliasFor(
            annotation = EnableAutoConfiguration.class,
            attribute = "excludeName"
        )
        String[] excludeName() default {};
    
        @AliasFor(
            annotation = ComponentScan.class,
            attribute = "basePackages"
        )
        String[] scanBasePackages() default {};
    
        @AliasFor(
            annotation = ComponentScan.class,
            attribute = "basePackageClasses"
        )
        Class<?>[] scanBasePackageClasses() default {};
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    综合@AliasFor注解的功能特点, 可得如下结论:

    1. @SpringBootApplication@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan组成(这个结论与@AliasFor无关, 是SpringBoot的注解继承特性)

    代码片段如下(摘取自@SpringBootApplication源码):

    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan(
        excludeFilters = {@Filter(
        type = FilterType.CUSTOM,
        classes = {TypeExcludeFilter.class}
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. @SpringBootApplication(excludeName = "xxx")等价于@EnableAutoConfiguration(excludeName="xxx")

    代码片段如下(摘取自@SpringBootApplication源码):

        @AliasFor(
            annotation = EnableAutoConfiguration.class,
            attribute = "exclude"
        )
        Class<?>[] exclude() default {};
    
        @AliasFor(
            annotation = EnableAutoConfiguration.class,
            attribute = "excludeName"
        )
        String[] excludeName() default {};
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    其中,annotation表示注解名,attribute表示这个注解内的关键字, String[] excludeName() default {};表示该注解+关键字代指@SpringBootApplication中的关键字(根据@AliasFor第二个性质,即帮助某个属性继承其他注解的功能)

    1. excludeName关键字等价于exclude关键字, 根据@AliasFor第一个性质,即同一个注解中的两个属性, 互为别名(功能相同))
  • 相关阅读:
    Mac | 关于 Mac 桌面文件无法显示
    JavaScript查找最长的公共前缀
    [算法刷题笔记]哈希表(1)
    2022/9/17(cf·div2)https://codeforces.com/contest/1728
    Vue3中props的原理与使用
    vue组件传参
    万字长文!对比分析了多款存储方案,KeeWiDB最终选择自己来
    vs中C++编译未生成exe
    黑马头条项目经验&BUG
    基于SpringBoot+Redis的前后端分离外卖项目-苍穹外卖(五)
  • 原文地址:https://blog.csdn.net/weixin_43899069/article/details/126532514