自定义注释
-
基本定义: 属性通过 属性名() 的方式声明,可以通过default 设置默认值,这样在使用注释时可以不给属性赋值,否则使用时声明的属性必需赋值
public @interface myAnnot {
int id() default -1;
String desc();
}
-
元注释: Meta Annotation,通俗的讲就是用来注释注释 的注释。JDK定义了4个元注释:@Target,@Retention,@Documented,@Inherited
@Target 标示自定义的Annotation可用来注释哪些元素,例如Class、Method 示例
@Target({ElementType.METHOD,ElementType.ANNOTATION_TYPE})
-
@Retention 标示自定义的Annotation的生命周期,可选值为RetentionPolicy枚举值
-
RetentionPolicy.SOURCE
标示自定义的Annotation仅存在于源代码中,编译时丢弃
-
RetentionPolicy.CLASS
标示自定义的Annotation会编译到Class文件中,但在运行加载时被丢弃
-
RetentionPolicy.RUNTIME
标示自定义的Annotation在运行加载时被一起加载,可以通过反射机制读取。
@Documented 标示自定义的Annotation会包含在JavaDoc中,其实这个我不关心
@Inherited 标示允许子类继承父类的自定义的Annotation
-
@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
-
核心方法
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的简单实现框架
-
核心方法
Class> Class.forName(clsName) 反射获取Class类
Constructor> Class.getConstructor(Class>... parameterTypes) 反射获取指定参数形态的构造器(可以理解为构造函数对象)
T Class.newInstance() 无构造参数方式创建类实例对象。
T Constructor.newInstance(Object... args) 有构造参数方式创建类实例对象
-
框架方案
搭建IoC容器,容器需要实现通过输入类的全名(包括命名空间)来创建类实例对象
功能的抽象接口。定义接入协议。
配置文件提供IoC容器需要的信息
-
简单示例
//接口
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 static Class 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();
-
利用注释进行依赖注入
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|