1. 注解 Annotation
最开学习Spring的时候,一般我们如果需要装配一个 bean
都是通过xml配置文件配置的。如下:
public class Test{
}
然后在xml的配置文件中:
<bean id="test" class="com.xxx.yyy.Test"/>
但是有了注解,可以很舒服的像下面这些写,只需要在类名上加上 @Service
注解就可以完成前面在XML配置文件中完成的工作。
@Service
public class DemoService{
}
使用注解可以提升开发的效率,观察一下大型互联网框架或者JDK底层的源码,有很多地方都使用到了注解。
2. 注解的构成
一个注解可以由三部分组成:
注解体、元注解、注解属性
。注解体指定了注解的名字,而元注解则标记了该注解的使用场景、留存时间等信息,而注解属性则指明该注解拥有的属性
2.1 注解体
注解体的这部分是比较简单的,只需要有一个@interface
标识的文件即可,如下代码,声明了一个名字叫Client
的注解体
public @interface Client {
}
2.2 元注解
有了注解体以后,我们需要知道这个注解使用的场景、生命周期、继承属性、文档信息等等,这部分信息使用元注解
去声明,并且元注解本身也是一个注解,JDK
源码中提供了4个元注解,分别是@Target 、@Retention、@Documented、@Inherited
:
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
boolean required() default true;
}
2.2.1 @Target
Target
注解限定了一个注解的使用场景,它的值可以有如下几种:
- ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
- ElementType.CONSTRUCTOR 可以给构造方法进行注解
- ElementType.FIELD 可以给属性进行注解
- ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
- ElementType.METHOD 可以给方法进行注解
- ElementType.PACKAGE 可以给一个包进行注解
- ElementType.PARAMETER 可以给一个方法内的参数进行注解
- ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举
在
Autowire
的 注解中,其 Target 注解的值为 CONSTRUCTOR、METHOD、PARAMETER、FIELD、ANNOTATION_TYPE 这 5 个值。这表示 Autowired 注解只能在构造方法、方法、方法形参、属性、类型这 5 种场景下使用。
2.2.2 @Retention
@Retention
注解用来标记这个注解的生命周期,也就是在程序执行的整个过程(包括加载、编译、等等)中的作用时间。它有如下几个可选值:
- RetentionPolicy.SOURCE。注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视
- RetentionPolicy.CLASS。注解只被保留到编译进行的时候,它并不会被加载到 JVM 中
- RetentionPolicy.RUNTIME。注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们。
Autowire
注解中,其Retention
注解的值为 RetentionPolicy.RUNTIME,说明该注解会保留到程序运行的时候
2.2.3 @Documented
@Documented
注解表示将注解信息写入到javadoc
文档中,默认情况下注解信息不会写入到文档中的。看自己是否有需要生成整个工程对应的API--javadoc
文档了。
2.2.4 @Inherited
@Inherited
注解标识子类将继承的父类的注解属性,类似Java里面的继承,父类的注解属性在子类中都有。
2.3 注解属性
注解属性类似于类方法的声明,注解属性里有三部分信息,分别是:属性名、数据类型、默认值。这里需要注意的是注解属性这部分可以是空的,比如我们常见的@Overrider
的代码如下,它只有注解名和元注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
而对于上面我们说的@Autowired
注解来说,它声明了一个名字为required
的boolean类型默认值为true的注解属性。
3. 手写一个注解
通过上面我们知道了注解的三个重要组成部分,注解体、元注解、注解属性。先写一个
/**
* 声明一个注解体为Client的注解
*/
public @interface Client {
/**
* 声明一个类型为string名叫doing并且默认值为todo的注解属性
* @return
*/
String doing() default "todo";
}
/**
* 对应的用法,如果没有注解属性,只需要写@Client即可,有默认值防止报错,此处没有写也可以
* 如果只有一个注解熟悉,不需要指定名称了,直接写就OK了
*/
public class Test {
@Client(doing="see_omething")
public void see(){
}
}
网友评论