Annotation 使用备忘2
title: Annotation 使用备忘
date: 2018-01-02 20:48:43
tags: [Annotation]
categories: [Programming,Java]
概述
本文记录使用 javapoet 以及 auto-service 进行编译时注解的过程以及注意点.
最近又使用了一次编译时注解,期间产生了不少问题.
术语的解释
Element
这个代表被注解的元素.这个类有个很重要的方法,getEnclosingElement:这方法的含义是获取 包裹 element 最外围的元素.比如类的最外围的元素是 package.
PackageElement pkgElement = (PackageElement) element.getEnclosingElement();
其他方法都很简单.
javapoet 库中一些重要的接口和方法
- TypeName: 对应了 java 代码中的一个类型元素,常用于声明一个方法参数,还有一些 collection 范型使用.
// 用来定一个 ComponentInfo 类的元素类型
TypeName mComponentInfoClassName = ClassName.get(ComponentInfo.class);
- ParameterizedTypeName 用来声明一个方法的参数.有个 get 方法,这个方法第一个参数是声明原生的类型,后面一个可变参数,声明第一个参数的参数.
// 声明一个参数的类型是 Map<String,List<ComponentInfo>>
ParameterizedTypeName paramListComponent = ParameterizedTypeName.get(ClassName.get(List.class), mComponentInfoClassName);
ParameterizedTypeName moduleLoaderParameter = ParameterizedTypeName.get(
ClassName.get(Map.class),
ClassName.get(String.class),
paramListComponent
);
- ParameterSpec
这个类代表方法的参数
// 声明一个方法的参数是:final Map<String,List<ComponentInfo>> targetMap.
ParameterSpec injectParameterSpec = ParameterSpec.builder(moduleLoaderParameter, "targetMap", Modifier.FINAL).build();
- MethodSpec.Builder
方法的构造器,用来构造一个方法.
// 用来构造一个私有方法,名字叫 inject ,参数是 Map<String,List<ComponentInfo>> targetMap,String group,String pkg,String name,int type
MethodSpec.Builder injectElementBuilder = MethodSpec.methodBuilder("inject")
.addModifiers(Modifier.PRIVATE)
.addParameter(injectParameterSpec)
.addParameter(String.class, "group")
.addParameter(String.class, "pkg")
.addParameter(String.class, "name")
.addParameter(int.class, "type");
这个构造还可以继续添加语句
injectElementBuilder.addStatement("List<$T> list = targetMap.get(name)", ComponentInfo.class)
.beginControlFlow("if( list == null )")
.addStatement("list = new $T<>()", ArrayList.class)
.addStatement("targetMap.put(group, list)")
.endControlFlow()
.addStatement("ComponentInfo info = new ComponentInfo(type, group, pkg, name)")
.beginControlFlow("try")
.addStatement(" info.setClazz(Class.forName(pkg + name))")
.nextControlFlow("catch(Exception e)")
.addStatement("e.printStackTrace()")
.endControlFlow()
.addStatement("list.add(info)");
注意其中的两个 ControlFlow .
- TypeSpec
用来声明一个类的描述
// 声明一个类,类名是 className,里面有两个方法
TypeSpec typeSpec = TypeSpec.classBuilder("className")
.addModifiers(Modifier.PUBLIC)
.addMethod(injectElementMethod)
.addMethod(injectMethodSpec)
.build();
- JavaFile
代表一个输出的 java 文件.
// 声明一个包名为 : com.steve.pkg 的java 文件.文件描述用的是一个 TypeSpec
JavaFile javaFile = JavaFile.builder("com.steve.pkg", typeSpec).build();
使用的注意事项
- 新版的 studio 以及不需要 android-apt
- 对于注解器的依赖可以通过 annotationProcessor project(':processor') 来对注解器工程进行依赖
- 对于注解配置选项可以在 gradle 中进行配置
defaultConfig {
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode rootProject.ext.android.versionCode
versionName rootProject.ext.android.versionName
javaCompileOptions {
annotationProcessorOptions {
arguments = [moduleName: project.getName()]
}
}
}
- 对于注解器的注册,@AutoService(Processor.class),不要写错了,写成 process
- 注解器的配置项需要在注解器中声明 @SupportedOptions("moduleName")
- 注解器中的 log 不要随便打 error,不然就会停止解析,这点和 android 中的 log 有些差异.
Annotation 使用备忘2的更多相关文章
- Annotation 使用备忘
title: Annotation 使用备忘 date: 2016-11-16 23:16:43 tags: [Annotation] categories: [Programming,Java] - ...
- Spring boot 注解简单备忘
Spring boot 注解简单备忘 1.定义注解 package com.space.aspect.anno;import java.lang.annotation.*; /** * 定义系统日志注 ...
- GIS部分理论知识备忘随笔
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.高斯克吕格投影带换算 某坐标的经度为112度,其投影的6度带和3度带 ...
- python序列,字典备忘
初识python备忘: 序列:列表,字符串,元组len(d),d[id],del d[id],data in d函数:cmp(x,y),len(seq),list(seq)根据字符串创建列表,max( ...
- Vi命令备忘
备忘 Ctrl+u:向文件首翻半屏: Ctrl+d:向文件尾翻半屏: Ctrl+f:向文件尾翻一屏: Ctrl+b:向文件首翻一屏: Esc:从编辑模式切换到命令模式: ZZ:命令模式下保存当前文件所 ...
- ExtJs4常用配置方法备忘
viewport布局常用属性 new Ext.Viewport({ layout: "border", renderTo: Ext.getBody(), defaults: { b ...
- [备忘] Automatically reset Windows Update components
这两天遇到Windows 10的更新问题,官方有一个小工具,可以用来修复Windows Update的问题,备忘如下 https://support.microsoft.com/en-us/kb/97 ...
- ECMAScript 5(ES5)中bind方法简介备忘
一直以来对和this有关的东西模糊不清,譬如call.apply等等.这次看到一个和bind有关的笔试题,故记此文以备忘. bind和call以及apply一样,都是可以改变上下文的this指向的.不 ...
- MFC通过txt查找文件并进行复制-备忘
MFC基于对话框的Demo txt中每行一个23位的卡号. 文件夹中包含以卡号命名的图像文件.(fpt或者bmp文件) 要求遍历文件夹,找到txt中卡号所对应的图像文件,并复制出来. VC6.0写的. ...
随机推荐
- TensorFlow函数(七)tf.argmax()
tf.argmax(input, dimension, name=None) 参数: input:输入数据 dimension:按某维度查找. dimension=0:按列查找: dimension= ...
- webbench安装和简单使用
一.安装流程 wget http://home.tiscali.cz/~cz210552/distfiles/webbench-1.5.tar.gz tar zxvf webbench-1.5.tar ...
- Uva514
https://vjudge.net/problem/UVA-514 #include <bits/stdc++.h> using namespace std; ; int target[ ...
- Activiti6.0 工作流引擎 websocket即时聊天发图片文字 好友群组 SSM源码
即时通讯:支持好友,群组,发图片.文件,消息声音提醒,离线消息,保留聊天记录 (即时聊天功能支持手机端,详情下面有截图) 工作流模块---------------------------------- ...
- 学习JavaWeb aop两种配置方式
aop aop:面向切面编程,它可以解决重复代码. aop有两种方式: 一..xml方式 1.在springmvc-servlet.xml中配置aop,应用bean文件: <!--aop配置-- ...
- CodeIgniter Doctrine2基本使用(二)(转)
CodeIgniter Doctrine2基本使用(二) 继上次写的一篇文章<CodeIgniter Doctrine2基本使用(一)>写到操作实体的之通过Channel这个实体向数据库表 ...
- Delphi在Android下使用Java库
本文将以Android的USB串口通讯库为例,介绍Delphi如何在Android中使用Java的库. USB串口通讯库地址: https://github.com/felHR85/UsbSerial ...
- 一图看懂hadoop MapReduce工作原理
MapReduce执行流程及单词统计WordCount示例
- 【转】Vulhub - 开源的安全漏洞学习与复现项目
转载于:https://uk.v2ex.com/t/485611#reply15 Vulhub 是一个面向大众的开源漏洞靶场,无需 docker 知识,简单执行两条命令即可编译.运行一个完整的漏洞靶场 ...
- 实际项目开发过程中常用C语言函数的9大用法
C语言是当中最广泛的计算机编程语言,是所有计算机编程语言的祖先,其他计算机编程语言包括当前流行的Java语言,都是用C语言实现的,C语言是编程效率最高的计算机语言,既能完成上层应用开发,也能完成底层硬 ...