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

Posted 来老铁干了这碗代码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了@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;

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

可以看到,按照@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 "";
 

可以看到,@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 ;

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

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

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

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = @Filter(
    type = FilterType.CUSTOM,
    classes = TypeExcludeFilter.class
)
  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 ;

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

  1. excludeName关键字等价于exclude关键字, 根据@AliasFor第一个性质,即同一个注解中的两个属性, 互为别名(功能相同))

以上是关于@AliasFor注解详解(结合源码分析)的主要内容,如果未能解决你的问题,请参考以下文章

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

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

从Spring源码中学习如何查找自定义注解

Spring声明式事务注解@Transactional详解

SpringBoot 中的 @AliasFor注解

Sring 的 @AliasFor 使用规则