框架原理(注解加反射):注解
注解
概念
注解是Java 1.5 引入的,目前已被广泛应用于各种Java
框架,如Hibernate,Jersey,Spring。注解相当于是一
种嵌入在程序中的 元数据 ,可以使用注解解析工具或编
译器对其进行解析,也可以指定注解在编译期或运行期
有效。在注解诞生之前,程序的元数据存在的形式仅限
于java注释或javadoc,但注解可以提供更多功能,它不
仅包含元数据,还能作用于运行期,注解解析器能够使
用注解决定处理流程。
Annotation(注解)就是Java提供了一种元程序中的元素关
联任何信息和任何元数据 (metadata)的途径和方法。
Annotation是一个接口,程序可以通过反射来获取指定
程序元素的Annotation对象,然后通过Annotation对象来
获取注解里面的元数据。注解API非常强大,被广泛应用
于各种Java框架。
分类
根据注解参数的个数分类
1)、标记注解:一个没有成员定义的Annotation类型被
称为标记注解。
2)、单值注解:只有一个值
3)、完整注解:拥有多个值
根据注解使用方法和用途分类
1)、JDK内置系统注解
2)、元注解
3)、自定义注解
内置注解
-
* @Override :重写父类方法 * @Deprecated:标记已过时,不推荐使用,但可以使用的方法 * @SuppressWarnings:抑制编译器警告,该注解仅仅告知编译器,忽略它们产 生了特殊警告。
定义注解
@interface:用来声明一个注解。注解类里的每一个方法
实际上是声明了一个配置参数。方法的名称就是参数的
名称,返回值类型就是参数的类型。可以通过default来
声明参数的默认值。
package com.lwf.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author lwf
* @title: MyAnnotation
* @projectName ReflectLearn
* @description: TODO
* @date 2020/10/2216:44
*/
@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
public String name() default "注解";
public int value() default 0;
}
元注解(注解其他注解)
@Target:表明注解存放位置 存放枚举类型 ElementType
CONSTRUCTOR:用于描述构造器
FIELD:用于描述域
LOCAL_VARIABLE:用于描述局部变量
METHOD:用于描述方法
PACKAGE:用于描述包
PARAMETER:用于描述参数
TYPE:用于描述类、接口(包括注解类型) 或enum声明
@Retention:表示需要在什么级别保存该注释信息,用于描述注解的
生命周期 存放枚举类型 RetentionPoicy
SOURCE:在源文件中有效(即源文件保留)
CLASS:在class文件中有效(即class保留)
RUNTIME:在运行时有效(即运行时保留)
@Documented :表示使用该注解的元素应被javadoc或类似工具文档化,
它应用于类型声明,类型声明的注解会影响客户端对注
解元素的使用。
@Inherited :表示一个注解类型会被自动继承,如果用户在类声明的
时候查询注解类型,同时类声明中也没有这个类型的注
解,那么注解类型会自动查询该类的父类,这个过程将
会不停地重复,直到该类型的注解被找到为止,或是到
达类结构的顶层(Object)。
代码
-
定义注解
package com.lwf.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author lwf * @title: MyAnnotationPlus * @projectName ReflectLearn * @description: TODO * @date 2020/10/2217:47 */ @Target({ElementType.METHOD,ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotationPlus { public String value() default "lwf"; }
2.定义javabean并使用以上注解 MyAnnotationPlus
package com.lwf.annotation; /** * @author lwf * @title: Student * @projectName ReflectLearn * @description: TODO * @date 2020/10/2217:49 */ public class Student { private int id; @MyAnnotationPlus private String name; @MyAnnotationPlus("上饶") private String city; public Student() { } public Student(int id) { this.id = id; } public Student(int id, String name, String city) { this.id = id; this.name = name; this.city = city; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } @Override public String toString() { return "Student{" + "id=" + id + ", name='" + name + '\'' + ", city='" + city + '\'' + '}'; } }
-
定义解析器,将注解中的值通过反射将值给pojo类
package com.lwf.annotation; import java.lang.reflect.Field; /** * @author lwf * @title: LearnPlus * @projectName ReflectLearn * @description: 解析 将 MyAnnotationPlus接口值给Student的属性 * @date 2020/10/2217:51 */ public class LearnPlus<T> { public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException { Student student=Student.class.newInstance(); new LearnPlus<Student>().getObject("com.lwf.annotation.Student",student); System.out.println(student); } /** * MyAnnotationPlus注解解析器 * @param str * @param obj * @return * @throws ClassNotFoundException * @throws IllegalAccessException */ public boolean getObject(String str,T obj) throws ClassNotFoundException, IllegalAccessException { Class c= Class.forName(str); for (Field field : c.getDeclaredFields()) { if(field.isAnnotationPresent(MyAnnotationPlus.class)){ field.setAccessible(true); if(field.get(obj)==null){ field.set(obj, field.getAnnotation(MyAnnotationPlus.class).value()); } } } return true; } }