Java中的注解@Xxx

@Target

  • 作用: 指明了修饰的这个注解的使用范围, 即被描述的注解可以用在哪里
@Target(ElementType.Type)
  • ElementType取值的类型:
    • TYPE: 类,接口或者枚举
    • FIELD: 域,包含枚举常量
    • METHOD: 方法
    • PARAMETER: 参数
    • CONSTRUCTOR: 构造方法
    • LOCAL_VARIABLE: 局部变量
    • ANNOTATION_TYPE: 注解类型
    • PACKAGE:

@Retention

  • 作用: 指明修饰的注解的生存周期, 即会保留到哪个阶段
  • RetentionPolicy的取值类型有三种:
    • SOURCE: 源码级别保留,编译后即丢弃
    • CLASS: 编译级别保留,编译后的class文件中存在,在jvm运行时丢弃,这是默认值
    • RUNTIME: 运行级别保留,编译后的class文件中存在,在jvm运行时保留,可以被反射调用

@Documented

  • 作用: 指明修饰的注解,可以被例如javadoc此类的工具文档化
    • 只负责标记
    • 没有成员取值

@Inherited

  • 作用: 允许子类继承父类中的注解
  • @Inherited需要和@AliasFor一起使用: 在子注解对应的属性使用@AliasFor
    • 注解是可以继承的,但是注解是不能继承父注解的属性
    • 也就是说,在类扫描时的注解的属性值依然是父注解的属性值,而不是自定义注解的属性值
    • 需要在注解的属性上使用@AliasFor

@ComponentScan

  • 作用: 定义扫描的路径从中找出标识了需要装配的类自动装配到spring的bean容器中
  • 默认会扫描该类所在的包下所有的配置类
  • @ComponentScan中的参数类型:
    • value: 用于对指定包的路径进行扫描
    • basePackages: 用于指定包的路径进行扫描,用法和value一样.建议使用value
    • basePackageClasses: 用于对指定某个类的所在的包的路径进行扫描
    • nameGenerator: 用于为Spring容器中的检测到bean组件命名
    • useDefaultFilters: 是否开启对 @Component,@Repository,@Service,@Controller的类进行检测
    • excludeFilters: 按照过滤条件进行排除
      • FilterType.ANNOTATION: 按照注解
      • FilterType.ASSIGNABLE_TYPE: 按照给定的类型
      • FilterType.ASPECTJ: 使用ASPECTJ表达式
      • FilterType.REGEX: 使用正则表达式
      • FilterType.CUSTOM: 按照自定义规则
    • includeFilters: 按照过滤条件进行包含
      • FilterType.ANNOTATION: 按照注解
      • FilterType.ASSIGNABLE_TYPE: 按照给定的类型
      • FilterType.ASPECTJ: 使用ASPECTJ表达式
      • FilterType.REGEX: 使用正则表达式
      • FilterType.CUSTOM: 按照自定义规则

@Filter

  • 作用: 配置过滤条件的过滤器注解
  • @Filter中的参数类型:
    • type
    • class

@interface

  • 作用: 自定义注解
  • 自动继承java.lang.annotation.Annotation接口,由编译程序自动完成其他细节
  • 在定义注解时,不能继承其他的注解或接口
  • @interface用来声明一个注解:
    • 其中的每一个方法实际上是声明一个配置参数
    • 方法的名称就是参数的名称
    • 方法的返回值类型就是参数的类型
    • 返回值类型只能是基本类型,Class,String,enum
    • 可以通过default来声明参数的默认值
  • 定义注解的格式:
public @interface 注解名 {定义体}
  • 注解参数支持的数据类型:
    • 基本数据类型: int,float,boolean,byte,double,char,long,short
    • String类型
    • Class类型
    • enum类型
    • Annotation类型
    • 以上类型组合的数组
  • Annotation类型中参数设定规则:
    • 只能用public或default默认访问权修饰:
    • 参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和String,Enum,Class,annotations等数据类型,以及这一些类型的数组
    • 如果只有一个参数成员,最好把参数名称设为value,后加小括号
  • 注解元素的默认值:
    • 注解元素必须有确定的值
    • 要么在定义注解的默认值中指定,要么在使用注解时指定,非基本类型的注解元素的值不可为null
    • 因此使用空字符串或0作为默认值约束
  • 这个约束使得处理器很难表现一个元素的存在或缺失的状态:
    • 因为每个注解的声明中,所有元素都存在,并且都具有相应的值
  • 为了绕开这个约束,只能定义一些特殊的值(比如空字符串或者负数),表示某个元素不存在

@AliasFor

  • 作用: 为注解的属性添加别名
  • 在同一个注解内,对两个不同的属性一起使用,互为别名:
    • 无论为哪个属性名设置属性值,另一个属性名也是同样的属性值
    • 互为别名的属性值必须相同,否则会报错
    • 属性必须要有默认的属性值
public @interface RequestMapping {
   
    @AliasFor("path") 			// 此时path和value值必须是一样的,否则会报错
    String[] value() default {};

    @AliasFor("value") 			// 此时path和value值必须是一样的,否则会报错
    String[] path() default {};
    
}
  • 显式的覆盖元注解中的属性:
    • 显式的为元注解的属性设置别名
    • 属性类型,属性默认值必须相同
    • @AliasFor只能为作为当前注解的元注解起别名
  • 示例:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AopConfig.class)
public class AopUtilsTest {}

要想替换 @ContextConfiguration(classes = AopConfig.class) 注解,可以这样定义一个标签:

@Retention(RetentionPolicy.RUNTIME)
@ContextConfiguration
public @interface Context {
    @AliasFor(value = "classes", annotation = ContextConfiguration.class)
    Class<?>[] cs() default {};
}
  1. 因为 @ContextConfiguration注解本身被定义为 @Inherited的,所以Context注解即可理解为继承 @ContextConfiguration注解
  2. cs属性等同于 @ContextConfiguration属性中的classes属性.使用了 @AliasFor标签,分别设置:
    1. value: 作为哪个属性的别名
    2. annotation: 作为哪个注解的别名

使用Context标签的可以达到同样效果:

@RunWith(SpringJUnit4ClassRunner.class)
@STC(cs = AopConfig.class)
public class AopUtilsTest {}
  • 在一个注解中隐式声明别名:
 @ContextConfiguration
 public @interface MyTestConfig {

    @AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
    String[] value() default {};

    @AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
    String[] groovyScripts() default {};

    @AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
    String[] xmlFiles() default {};
 }

这就是在统一注解中隐式声明别名:

  1. MyTestConfig注解中 ,value,groovyScripts,xmlFiles都定义为@AliasFor(annotation = ContextConfiguration.class, attribute = “locations”)的别名
  2. 在这个注解中 ,value,groovyScripts和xmlFiles也互为别名
  • 别名的传递:
    • @AliasFor注解是允许别名之间的传递的:
      • 如果A是B的别名,并且B是C的别名,那么A是C的别名
@MyTestConfig
 public @interface GroovyOrXmlTestConfig {

    @AliasFor(annotation = MyTestConfig.class, attribute = "groovyScripts")
    String[] groovy() default {};

    @AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
    String[] xml() default {};
 }
  1. GroovyOrXmlTestConfig@MyTestConfig作为元注解
  2. 定义了groovy属性,并作为MyTestConfig中的groovyScripts属性的别名
  3. 定义了xml属性,并作为ContextConfiguration中的locations属性的别名
  4. 因为MyTestConfig中的groovyScripts属性本身就是ContextConfiguration中的locations属性的别名,所以xml属性和groovy属性也互为别名
  • @Alias中的属性:
    • annotation: 类类型,别名属性的类的类型,即别名的属性属于哪个注解类
    • attribute: 需要别名的属性
    • value: 属性的别名

@Import

  • @Import支持导入普通的Java类,并声明为一个Bean
  • @Import使用场景:
    • @Import主要用在基于Java代码显式创建bean的过程中
    • @Import用于将多个分散的Java Config配置类融合成一个完整的config类
  • 配置类的组合主要发生在跨模块或者跨包的配置类引用过程中: 将多个按功能或者按业务划分的配置文件导入到单个配置文件中,避免将所有配置写在一个配置中
  • @Import与@ImportResource注解的作用类似
  • 使用@ImportResource和@Value可以进行资源文件的读取
发布了113 篇原创文章 · 获赞 95 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/JewaveOxford/article/details/103188895