Java注解(二):注解处理器
来源:互联网 发布:温度测试仪软件 编辑:程序博客网 时间:2024/06/05 17:14
前言
在上篇博客中曾经提到过,注解实际上只是一个元数据,一个躯壳!只有通过注解处理器才能为你的注解赋予灵魂!没有注解处理器的注解和普通注释并没有什么区别! 在上篇博客中,我们已经学会了如何制造躯壳,那么在本篇中,我们将学习如何为注解赋予灵魂–注解处理器。
目标
本篇博客我们将会介绍如何写注解处理器,并且完成一个小例子(将在配置类中@Config通过@Alias注册了别名的类,将使用一个Map< String , Class< ? >>存放别名与注册类的关系。)
注解处理器
在写注解处理前,首先我们需要一些预备知识。
AnnotatedElement接口
为了使程序员能够通过反射对注解进行一系列操作,JDK定义了AnnotatedElement这个接口,其中反射机制的主要成员类Class、Method、Field、Package、Constructor、Parameter等都实现了该接口,现在先介绍一些该接口的方法的作用。
/** *判断是否含有指定注解 *@param annotationClass 需判断的注解类型 *@since JDK1.5 **/boolean isAnnotationPresent(Class< ? extends Annotation> annotationClass);/** *获取指定注解的实例 *@param annotationClass 指定注解类型 *@since JDK1.5 **/<T extends Annotation> T getAnnotation(Class<T> annotationClass);/** *获取所有注解实例,返回实例数组 *@since JDK1.5 **/Annotation[] getAnnotations();/** *获取所有非继承的注解(即不包括使用了@Inherited的注解,通过父类继承而来的),返回实例数组 *@since JDK1.5 **/Annotation[] getDeclaredAnnotations();/** *从非继承的注解中获取指定注解实例 *@param annotationClass 指定注解类型 *@since JDK1.8 */< T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass)/** *返回指定重复注解的实例集合 *@param annotationClass 指定注解类型 *@since JDK1.8 */< T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass)/** *返回非继承的 指定重复注解的实例集合 *@param annotationClass 指定注解类型 *@since JDK1.8 **/< T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass)
实战
目标:接下来我们将要实现,用@config标志一个配置类,在配置类中通过方法返回值来表示你要注册进容器的类的类型。通过@Alias表示是需要注册的类及对应的别名。如果@Alias没有设置值,则使用方法名作为别名存储。最终返回一个map容器。里面存储的是类别名与类的关系。
首先创建两个注解,一个代表配置类的标记型注解@config,一个用于注册别名的@Alias(name=”“)。
/** * 配置类标注注解 */@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface Config {}/** *别名注册 注解 */@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface Alias { String value() default "";}
对应注解的处理器
/** * @Config注解处理器 */public class ConfigHandler { /** * 判断参数类型是否包含config注解 * @param 参数类型 */ public static boolean hasAnnotation(Class<?> classz){ if(null == classz) return false; if(classz.isAnnotationPresent(Config.class)){ return true; } return false; }}public class AliasHandler { private static Map<String,Class> map ; static{ map = new HashMap<>(); } /** * 判断参数类型是否包含Alias注解 * @param 参数类型 * @return */ public static boolean hasAnnotation(Method method){ if(null == method) return false; if(method.isAnnotationPresent(Alias.class)){ return true; } return false; } public static Map<String,Class> handler(List<Method> methods){ methods.forEach(AliasHandler::handler); return map; } /** * 将每个方法解析并放进map中 * @param method */ public static void handler(Method method){ if(method == null) return ; Alias alias = method.getAnnotation(Alias.class); Class<?> returnType = method.getReturnType(); //如果Alias没有设置别名书名,则使用方法名作为别名 if(alias.value() == null || "".equals(alias.value())) map.put(method.getName(),returnType); else map.put(alias.value(),returnType); }}
最后的主方法运行:
@Configpublic class DemoConfig { @Alias Demo1 demo1(){ return new Demo1(); } @Alias("aliasDemo") Demo2 demo2(){ return new Demo2(); } public static void main(String[] args) { Class<DemoConfig> classz = DemoConfig.class; if(ConfigHandler.hasAnnotation(classz)){ List<Method> methods = CollectionUtils.toList(classz.getDeclaredMethods()); //过滤掉不包含@Alias注解的方法 methods.removeIf(method ->!AliasHandler.hasAnnotation(method)); Map<String,Class> map = AliasHandler.handler(methods); map.forEach((a,b)->{System.out.println(a+":"+b);}); }else throw new RuntimeException("不是配置类"); }}
最终打印结果:
aliasDemo:class two.demo.Demo2demo1:class two.demo.Demo1
阅读全文
0 0
- Java注解(二):注解处理器
- 【Java二十周年】Java注解处理器
- java 注解:注解(Annotation)--注解处理器
- Java注解(2)-自定义注解、注解处理器
- Java注解处理器
- Java注解处理器
- Java 注解处理器
- Java注解处理器
- JAVA注解及处理器
- Java 注解处理器
- JAVA 自定义注解(Annotation)-注解处理器
- Java注解(Annotation)-注解处理器小结
- Java注解与自定义注解处理器
- java注解(Annotation)--注解处理器
- Java注解处理器(编译时注解)
- Java注解和注解处理器使用详解
- Java: Annotation 浅析(二) 自定义注解处理器
- Java编程基础——编写注解处理器(二)
- linux,Ubuntu 16.04 设置MySQL远程访问权限
- 发送自定义事件
- max-points-on -a-line
- HDU3072 Intelligence System【最小树形图】
- 《数据库SQL实战》统计出当前各个title类型对应的员工当前薪水对应的平均工资。
- Java注解(二):注解处理器
- 树状数组求逆序对
- 堆棋子
- Mysql数据表管理
- 模板模式的应用
- RecastNavigation-NavMesh生成原理
- Android WebView 调试方法
- linux 内核驱动中对文件的读写
- 使用Python操作MongoDB