注解--Annotation
元注解
@Target :定义注解可以使用在什么地方:字段,方法,类,包,方法参数,局部变量,构造函数,注解。由ElementType枚举类型指定,详细信息请参考API
@Retention:定义注解停留在什么时期:源码,字节码,运行,
@Documented :说明该注解将被包含在javadoc中
@Inherited:说明子类可以继承父类中的该注解
自定义注解
使用@Interface声明,添加元注解@Target声明可以用在什么地方,@Retention停留在什么时期。例:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SetValue {
}
为注解声明属性:
Class beanClass();
注解属性的返回值类型限定为:CLASS,String,基本类型,枚举等,以及这些类型的数组类型。不可为自定义类
注解使用
在方法,属性,类等位置使用,例如:@Override、@RequestMapping、@Param.自定义注解使用方式相同
注解解析器
通过java反射机制解析类,方法,属性等的注解,然后根据注解信息做一些自定义操作,例如:
@Override 只停留在源码上,校验是否符合继承方法覆盖
@RequestMapping 停留在运行期,为spring mapping增加一条记录
@Param mybatis参数注解,为自动生成MAPPER服务
自定义注解解析器:参考
Field[] fields = t.getClass().getDeclaredFields();
System.out.println(fields.length);
for (Field field : fields) {
SetValue setValue= field.getAnnotation(SetValue.class);
if(setValue==null){
continue;
}
//查找DAO类
Class daoClass = setValue.beanClass();
Object daoIntance = MybatisDemoApplication.applicationContext.getBean(daoClass);
//取得参数的值
String[] paramFiledNames = setValue.paramFields();
Object[] paramValues = new Object[paramFiledNames.length];
for (int i=0;i<paramFiledNames.length;i++) {
String paramFiledName = paramFiledNames[i];
Field paramFiled = t.getClass().getDeclaredField(paramFiledName);
paramFiled.setAccessible(true);
Object paramValue = paramFiled.get(t);
paramValues[i] = paramValue;
}
//获取需要执行的方法
String executeMethod = setValue.executeMethod();
Class[] paramClass = setValue.paramClass();
Method method = daoClass.getMethod(executeMethod,paramClass);
method.setAccessible(true);
Object object = method.invoke(daoIntance,paramValues);
//获取目标值
String targetFiledName = setValue.targetField();
Field targetFiled = object.getClass().getDeclaredField(targetFiledName);
targetFiled.setAccessible(true);
Object targetValue = targetFiled.get(object);
field.setAccessible(true);
field.set(t,targetValue);
}