(一):java元注解
java的最基本的几个注解主要有一下几个
@Target:该注解主要是作用在方法,属性,类等上
@Retention:主要有三个参数
- SOURCE:当前注解编译器可见,但是不会写入到class文件
- CLASS:类加载阶段会丢弃,但是会写入到class文件
- RUNTIME:永久保存下来
@Documented:注解是否应当被包含在 JavaDoc 文档中,通常不用,作用不是很大
@Inherited:是否允许子类继承该注解
(二):注解原理
java当中所有的注解都是实现了Annotation这个接口,如下图所示,
(三):注解解析
一个注解解析通常有两种方式:
编译期间直接进行扫描:根据注解的名字,来判断才程序应该做什么事情,比方说spring的注解component注解的源码如下,
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
*/
String value() default "";
}
spring是通过注解的名称来判断,spring应该对这个对象做什么事情,(实际上,是spring底层源码,通过识别注解的名字来判断的)
通过运行期间来进行反射 :
一个注解,实际上也是一个对象,所以的话,我们也可以通过java的反射机制来获取注解里面的相关内容,不多说,代码如下,
//运行在字段上的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnTargetField {
String value() default "我是定义在字段上的注解";
}
//运行在方法上的注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnTargetMethod {
String value() default "我是定义在方法上的注解";
}
//运行在参数上的注解
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnTargetParameter {
String value() default "我是定义在一个参数上的注解";
}
//运行在类上的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnTargetType {
String value() default "我是定义在类上的注解";
}
//测试类
@MyAnTargetType
public class AnnotationTest {
@MyAnTargetField
private String field="我是字段";
@MyAnTargetMethod
public void test(@MyAnTargetParameter String args)
{
System.out.println("参数值sdfsdf"+args);
}
public static void main(String[] args) {
// 获取类上的注解MyAnTargetType
MyAnTargetType t = AnnotationTest.class.getAnnotation(MyAnTargetType.class);
System.out.println("类上的注解值 === "+t.value());
MyAnTargetMethod tm = null;
try {
// 根据反射获取AnnotationTest类上的test方法
Method method = AnnotationTest.class.getDeclaredMethod("test",String.class);
// 获取方法上的注解MyAnTargetMethod
tm = method.getAnnotation(MyAnTargetMethod.class);
System.out.println("方法上的注解值 === "+tm.value());
// 获取方法上的所有参数注解 循环所有注解找到MyAnTargetParameter注解
Annotation[][] annotations = method.getParameterAnnotations();
for(Annotation[] tt : annotations){
for(Annotation t1:tt){
if(t1 instanceof MyAnTargetParameter){
System.out.println("参数上的注解值 === "+((MyAnTargetParameter) t1).value());
}
}
}
method.invoke(new AnnotationTest(), "改变默认参数");
// 获取AnnotationTest类上字段field的注解MyAnTargetField
MyAnTargetField fieldAn = AnnotationTest.class.getDeclaredField("field").getAnnotation(MyAnTargetField.class);
System.out.println("字段上的注解值 === "+fieldAn.value());
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果如下所示