Java中的注解
@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 {};
}
- 因为 @ContextConfiguration注解本身被定义为 @Inherited的,所以Context注解即可理解为继承 @ContextConfiguration注解
- cs属性等同于 @ContextConfiguration属性中的classes属性.使用了 @AliasFor标签,分别设置:
- value: 作为哪个属性的别名
- 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 {};
}
这就是在统一注解中隐式声明别名:
- 在MyTestConfig注解中 ,value,groovyScripts,xmlFiles都定义为@AliasFor(annotation = ContextConfiguration.class, attribute = “locations”)的别名
- 在这个注解中 ,value,groovyScripts和xmlFiles也互为别名
- 别名的传递:
- @AliasFor注解是允许别名之间的传递的:
- 如果A是B的别名,并且B是C的别名,那么A是C的别名
- @AliasFor注解是允许别名之间的传递的:
@MyTestConfig
public @interface GroovyOrXmlTestConfig {
@AliasFor(annotation = MyTestConfig.class, attribute = "groovyScripts")
String[] groovy() default {};
@AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
String[] xml() default {};
}
- GroovyOrXmlTestConfig把 @MyTestConfig作为元注解
- 定义了groovy属性,并作为MyTestConfig中的groovyScripts属性的别名
- 定义了xml属性,并作为ContextConfiguration中的locations属性的别名
- 因为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可以进行资源文件的读取