自定义注释
-
基本定义:
属性通过属性名()
的方式声明,可以通过default 设置默认值,这样在使用注释时可以不给属性赋值,否则使用时声明的属性必需赋值public @interface myAnnot { int id() default -1; String desc(); }
-
元注释:
@H_301_22@
Meta Annotation,通俗的讲就是用来注释注释
的注释。JDK定义了4个元注释:@Target,@Retention,@Documented,@Inherited
@Target
标示自定义的Annotation可用来注释哪些元素,例如Class、Method
示例@Target({ElementType.METHOD,ElementType.ANNOTATION_TYPE})
-
@H_301_22@@Retention
标示自定义的Annotation的生命周期,可选值为RetentionPolicy枚举值 -
RetentionPolicy.SOURCE
标示自定义的Annotation仅存在于源代码中,编译时丢弃
-
RetentionPolicy.CLASS
标示自定义的Annotation会编译到Class文件中,但在运行加载时被丢弃
-
RetentionPolicy.RUNTIME
标示自定义的Annotation在运行加载时被一起加载,可以通过反射机制读取。
@Documented
标示自定义的Annotation会包含在JavaDoc中,其实这个我不关心-
@Repeatable
JDK8新增的元注释,标示自定义的Annotation可以在一个目标上连续多次使用public @interface Schedules { Schedule[] value(); }
@Repeatable(Schedules.class)
public @interface Schedule {
String dayOfMonth();
String dayOfWeek();
String hour();
}@Schedule(dayOfMonth="last")
@Schedule(dayOfWeek="Fri",hour="23")
public void doPeriodicCleanup() { /*方法体/ } -
示例
@Retention(value = RetentionPolicy.RUNTIME) public @interface myAnnot { int id() default -1; String desc(); }
-
反射读取Annotation
@H_301_22@ -
核心方法
@H_301_22@ boolean isAnnotationPresent(Class> annotationClass)
判断该程序元素上是否存在指定类型的注解Annotation getAnnotation(Class> annotationClass)
包含继承自父类的注释Annotation[] getAnnotations()
包含继承自父类的注释Annotation getDeclaredAnnotation(Class> annotationClass)
不包含继承自父类的注释Annotation[] getDeclaredAnnotations()
不包含继承自父类的注释Annotation[] getAnnotationsByTpye(Class> annotationClass)
-
Annotation[] getDeclaredAnnotationsByTpye(Class> annotationClass)
public static List
read(Class > cls){ List annot_lst = new ArrayList (); for(Method m : cls.getDeclaredMethods()){ myAnnot my_annot = m.getAnnotation(myAnnot.class); annot_lst.add(String.format("%s's myannot id is %s,desc is %s",m.getName(),my_annot.id(),my_annot.desc())); } return annot_lst; }
如何使用注释进行依赖注入(DI)
控制反转IoC(Inversion of Control)思想
总的来说就是不通过New来创建对象,使用反射技术将对象创建权利转移给控制容器,IoC容器根据类加载器创建。-
IoC的简单实现框架
@H_301_22@ -
核心方法
@H_301_22@ Class> Class.forName(clsName)
反射获取Class类Constructor> Class.getConstructor(Class>... parameterTypes)
反射获取指定参数形态的构造器(可以理解为构造函数对象)T Class.newInstance()
无构造参数方式创建类实例对象。T Constructor.newInstance(Object... args)
有构造参数方式创建类实例对象-
框架方案
-
简单示例
//接口 com.sample.inf public interface IEntity { public void Start(); }
IoC容器
com.sample.core
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;//示例以IEntity作为唯一接入点
public class Repo {
@SuppressWarnings("unchecked")
public staticClass getClass(String className) throws ClassNotFoundException{
Class<?> clsType = Class.forName(className);
// 判断是否满足接口协议
if (!IEntity.class.isAssignableFrom(clsType))
{
throw new ClassNotFoundException();
}
return (Class) clsType;
}public static <W extends Object,T extends IEntity> T getEntity(String className,@SuppressWarnings("unchecked") W... args) throws InstantiationException,IllegalAccessException,IllegalArgumentException,InvocationTargetException,NoSuchMethodException,SecurityException,ClassNotFoundException{ return getEntity(getClass(className),args); } public static <W extends Object,T extends IEntity> T getEntity(Class <T> clsType,SecurityException{ T o = null; if(args.length > 0){ Class<?>[] parameterTypes = new Class<?>[args.length]; int index =0; for (W arg : args) { parameterTypes[index++] = arg.getClass(); } Constructor<T> co = clsType.getConstructor(parameterTypes); o = co.newInstance(args); } else { o = clsType.newInstance(); } return o; }
}
通过IoC容器创建实例对象
IEntity entityObj = Repo.getEntity("com.sample.Entity.FirstEntity"); entityObj.Start();
-
利用注释进行依赖注入
@H_301_22@ 通过约定的注释信息,提供给IoC容器创建实例对象的必要数据。