通过学习与使用square公司的开源项目Javapoet,来实现仓库层动态生成代码

创新互联主营思礼网站建设的网络公司,主营网站建设方案,手机APP定制开发,思礼h5小程序定制开发搭建,思礼网站营销推广欢迎思礼等地区企业咨询
安卓AOP三剑客: APT, AspectJ, Javassist
Android APT
APT(Annotation Processing Tool 的简称),可以在代码编译期解析注解,并且生成新的 Java 文件,减少手动的代码输入。现在有很多主流库都用上了 APT,比如 Dagger2, ButterKnife, EventBus3 等
代表框架:
使用姿势
1,在android工程中,创建一个java的Module,写一个类继承AbstractProcessor
- @AutoService(Processor.class) // javax.annotation.processing.IProcessor
 - @SupportedSourceVersion(SourceVersion.RELEASE_7) //java
 - @SupportedAnnotationTypes({ // 标注注解处理器支持的注解类型
 - "com.annotation.SingleDelegate",
 - "com.annotation.MultiDelegate"
 - })
 - public class AnnotationProcessor extends AbstractProcessor {
 - public static final String PACKAGE = "com.poet.delegate";
 - public static final String CLASS_DESC = "From poet compiler";
 - public Filer filer; //文件相关的辅助类
 - public Elements elements; //元素相关的辅助类
 - public Messager messager; //日志相关的辅助类
 - public Types types;
 - @Override
 - public boolean process(Set extends TypeElement> set, RoundEnvironment roundEnvironment) {
 - filer = processingEnv.getFiler();
 - elements = processingEnv.getElementUtils();
 - messager = processingEnv.getMessager();
 - types = processingEnv.getTypeUtils();
 - new SingleDelegateProcessor().process(set, roundEnvironment, this);
 - new MultiDelegateProcessor().process(set, roundEnvironment, this);
 - return true;
 - }
 - }
 
2,在继承AbstractProcessor类中的process方法,处理我们自定义的注解,生成代码:
- public class SingleDelegateProcessor implements IProcessor {
 - @Override
 - public void process(Set extends TypeElement> set, RoundEnvironment roundEnv,
 - AnnotationProcessor abstractProcessor) {
 - // 查询注解是否存在
 - Set extends Element> elementSet =
 - roundEnv.getElementsAnnotatedWith(SingleDelegate.class);
 - Set
 typeElementSet = ElementFilter.typesIn(elementSet); - if (typeElementSet == null || typeElementSet.isEmpty()) {
 - return;
 - }
 - // 循环处理注解
 - for (TypeElement typeElement : typeElementSet) {
 - if (!(typeElement.getKind() == ElementKind.INTERFACE)) { // 只处理接口类型
 - continue;
 - }
 - // 处理 SingleDelegate,只处理 annotation.classNameImpl() 不为空的注解
 - SingleDelegate annotation = typeElement.getAnnotation(SingleDelegate.class);
 - if ("".equals(annotation.classNameImpl())) {
 - continue;
 - }
 - Delegate delegate = annotation.delegate();
 - // 添加构造器
 - MethodSpec.Builder constructorBuilder = MethodSpec.constructorBuilder()
 - .addModifiers(Modifier.PUBLIC);
 - // 创建类名相关 class builder
 - TypeSpec.Builder builder =
 - ProcessUtils.createTypeSpecBuilder(typeElement, annotation.classNameImpl());
 - // 处理 delegate
 - builder = ProcessUtils.processDelegate(typeElement, builder,
 - constructorBuilder, delegate);
 - // 检查是否继承其它接口
 - builder = processSuperSingleDelegate(abstractProcessor, builder, constructorBuilder, typeElement);
 - // 完成构造器
 - builder.addMethod(constructorBuilder.build());
 - // 创建 JavaFile
 - JavaFile javaFile = JavaFile.builder(AnnotationProcessor.PACKAGE, builder.build()).build();
 - try {
 - javaFile.writeTo(abstractProcessor.filer);
 - } catch (IOException e) {
 - e.printStackTrace();
 - }
 - }
 - }
 
3,在项目Gradle中添加 annotationProcessor project 引用
- compile project(':apt-delegate-annotation')
 - annotationProcessor project(':apt-delegate-compiler')
 
4,如果有自定义注解的话,创建一个java的Module,专门放入自定义注解。项目与apt Module都需引用自定义注解Module
4-1,主工程:
- compile project(':apt-delegate-annotation')
 - annotationProcessor project(':apt-delegate-compiler')
 
4-2,apt Module:
- compile project(':apt-delegate-annotation')
 - compile 'com.google.auto.service:auto-service:1.0-rc2'
 - compile 'com.squareup:javapoet:1.4.0'
 
5,生成的源代码在build/generated/source/apt下可以看到
难点
就apt本身来说没有任何难点可言,难点一在于设计模式和解耦思想的灵活应用,二在与代码生成的繁琐,你可以手动字符串拼接,当然有更高级的玩法用squareup的javapoet,用建造者的模式构建出任何你想要的源代码
优点
它的强大之处无需多言,看代表框架的源码,你可以学到很多新姿势。总的一句话:它可以做任何你不想做的繁杂的工作,它可以帮你写任何你不想重复代码。懒人福利,老司机必备神技,可以提高车速,让你以任何姿势漂移。它可以生成任何源代码供你在任何地方使用,就像剑客的剑,快疾如风,无所不及
我想稍微研究一下,APT还可以在哪些地方使用,比如:Repository层?
APT在Repository层的尝试
了解APT与简单学习之后,搭建Repository层时,发现有一些简单,重复模版的代码
每一次添加新接口都需要简单地修改很多地方,能不能把一部分代码自动生成,减少改动的次数呢?
Repository层
IRemoteDataSource, RemoteDataSourceImpl
远程数据源,属于网络请求相关
ILocalDataSource, LocalDataSourceImpl
本地数据源,属于本地数据持久化相关
IRepository,RepositoryImpl
仓库代理类,代理远程数据源与本地数据源
Repository层APT设计思路
发现在具体实现类中,大多都是以代理类的形式调用:方法中调用代理对象,方法名称与参数,返回值类型都相同。显然可以进行APT的尝试
期望结果:
自定义注解设计
要想具体实现类自动生成,首先要知道需要什么:
自动生成java文件的类库,可以使用 squareup javapoet
自动生成类名字,代理对象,方法集需要通过自定义注解配置参数的形成,在AbstractProcessor中获取
Delegate
- @Retention(RetentionPolicy.SOURCE)
 - @Target(ElementType.TYPE)
 - public @interface Delegate {
 - /**
 - * delegate class package
 - */
 - String delegatePackage();
 - /**
 - * delegate class name
 - */
 - String delegateClassName();
 - /**
 - * delegate simple name
 - */
 - String delegateSimpleName();
 - }
 
SingleDelegate
- @Retention(RetentionPolicy.SOURCE)
 - @Target(ElementType.TYPE)
 - public @interface SingleDelegate {
 - /**
 - * impl class name
 - */
 - String classNameImpl();
 - /**
 - * delegate data
 - */
 - Delegate delegate();
 - }
 
MultiDelegate
- @Retention(RetentionPolicy.SOURCE)
 - @Target(ElementType.TYPE)
 - public @interface MultiDelegate {
 - /**
 - * impl class name
 - */
 - String classNameImpl();
 - /**
 - * delegate list
 - */
 - Delegate[] Delegates();
 - }
 
处理自定义的注解、生成代码
AnnotationProcessor
- @AutoService(Processor.class) // javax.annotation.processing.IProcessor
 - @SupportedSourceVersion(SourceVersion.RELEASE_7) //java
 - @SupportedAnnotationTypes({ // 标注注解处理器支持的注解类型
 - "com.annotation.SingleDelegate",
 - "com.annotation.MultiDelegate"
 - })
 - public class AnnotationProcessor extends AbstractProcessor {
 - public static final String PACKAGE = "com.poet.delegate";
 - public static final String CLASS_DESC = "From poet compiler";
 - public Filer filer; //文件相关的辅助类
 - public Elements elements; //元素相关的辅助类
 - public Messager messager; //日志相关的辅助类
 - public Types types;
 - @Override
 - public boolean process(Set extends TypeElement> set, RoundEnvironment roundEnvironment) {
 - filer = processingEnv.getFiler();
 - elements = processingEnv.getElementUtils();
 - messager = processingEnv.getMessager();
 - types = processingEnv.getTypeUtils();
 - new SingleDelegateProcessor().process(set, roundEnvironment, this);
 - new MultiDelegateProcessor().process(set, roundEnvironment, this);
 - return true;
 - }
 - }
 
                网页题目:安卓AOP三剑客之AndroidAPT技术浅谈
                
                分享URL:http://www.csdahua.cn/qtweb/news29/41729.html
            
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网