Annotation
注解
@Service
public class MessageServiceImpl implements MessageService{
public String getMessage() {
return "Hello World!";
}
}
本质上来说 Annotation(注解)是 Java 推出的一种注释机制,后面我们统一叫 Annotation,和普通的注释有个显著的特别,那就是Annotation 是可以在编译、运行阶段读取的,注释很明显不可以。
能够在编译、运行阶段读取信息,这就给了我们很多的扩展空间,而且不会污染源代码。我们可以借助它来实现一些增强功能,在Spring当中就重度使用了 Annotation,通过运行阶段动态的获取Annotation 从而完成很多自定义的行为,所以如果不了解Annotation,那学习 Spring 就没有办法进行下去了。
从另外一个角度来看,Annotation 也是一个 Java 类,只是这个类太特殊了点。我们可以先看看上面的 Service 这个 Annotation 的源代码
-
@Target
java.lang.annotation.Target
自身也是一个注解,它只有一个数组属性,用于设定该注解的目标范围,比如说可以作用于类或者方法等。因为是数组,所以可以同时设定多个范围具体可以作用的类型配置在
java.lang.annotation.ElementType
枚举类中,我们说几个常用的-
ElementType.TYPE
可以作用于 类、接口类、枚举类上
-
ElementType.FlELD
可以作用于类的属性上
-
ElementType.METHOD
可以作用于类的方法上
-
ElementType.PARAMETER
可以作用于类的参数
-
如果想要同时作用于类和方法上,可以:
@Target({ElementType.TYPE,ElementType.METHOD})
如果某个Annotation的Target设定为METHOD,那就只能在方法上引用,其他Target也类似
例子
- 1 ElementType.TYPE
@Service
public class MessageServiceImpl implements MessageService{
public String getMessage() {
return "Hello World!";
}
}
- 2 ElementType.METHOD
public class MessageServiceImpl implements MessageService{
@ResponseBody
public String getMessage() {
return "Hello World!";
}
}
- 3 ElementType.FIELD
public class MessageServiceImpl implements MessageService{
@Autowired
private WorkspaceService workspaceService;
}
- 4 ElementType.PARAMETER
public class MessageServiceImpl implements MessageService{
public String getMessage(@RequestParam("msg")String msg) {
return "Hello "+msg;
}
}
- @Retention
java.lang.annotation.Retention
自身也是一个注解,它用于声明该注解的生命周期,简单的来说就是在 Java 编译、运行的哪个环节有效,它的值定义在 java.lang.annotation.RetentionPolicy
枚举类中,有三个值可以选择
-
SOURCE: 也就是说是纯注释作用
-
CLASS: 也就是在编译阶段是有效的
-
RUNTIME: 在运行时有效
@Retention(RetentionPolicy.RUNTIME)
这个代码表示的就是在运行期间有效
如果是我们自己定义的 Annotation ,一般我们都会设置成
RUNTIME
-
@Documented
自身也是一个注解,它的作用java.lang.annotation.Documented
是将注解中的元素包含到 JavaDoc 文档中,一般情况下,都会添加这个注解的。 -
@interface
@interface
就是声明当前的 Java 类型是 Annotation,固定语法就是这样写就好 -
Annotation 属性
String value() default "";
Annotation 的属性有点像类的属性一样,它约定了属性的类型(这个类型是基础类型:String、boolean、int、long),和属性名称(默认名称是 value ,在引用的时候可以省略),default 代表的是默认值。
有了这个属性,我们就可以正式的引用一个 Annotation 啦,比如
import org.springframework.stereotype.Service;
@Service
public class Demo {
}
注意,Annotation 也是 Java 类,所以一样需要 import 的
上面的 @service
也可以写成
import org.springframework.stereotype.Service;
@Service(value="Demo")
public class Demo {
}
因为我们说过 value 是默认属性名称是可以缩写的,所以上面的代码
等同于
import org.springframework.stereotype.Service;
@Service("Demo")
public class Demo {
}
Annotation 属性是可以有多个的,比如下面的一个注解类
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
@AliasFor("name")
String value() default "";
@AliasFor("value")
String name() default "";
boolean required() default true;
String defaultValue() default ValueConstants.DEFAULT_NONE;
}
在属性的代码上,我们看到@AliasFor("name")
这个是别名的意思就是说这个属性用这个别名也可以访问到,所以下面的代码是一样的意思
@RequestParam("key")
@RequestParam(value="key")
@RequestParam(name="key")