先来说一下大家熟悉的面向对象编程:面向对象的特点是 继承、多态和封装 。而封装就要求将功能分散到不同的对象中去,这在缺点就是分散代码的同时,也增加了代码的重复性 。

比如我

895208d507204a9e71a0525514a8fe0d.png

其实在

代码demo链接

1、APT + JavaPoet

APT(Annotation Processing Tool 的简称),可以在 代码 ,结合JavaPoet 生成新的 Java 文件,减少手动的代码输入。现在有很多主流库都用上了 APT,比如 Dagger2, ButterKnife, EventBus3 等

更多可以参考编译时注解之APT

1、定义注解

例如

@Retention(RetentionPolicy.CLASS)

@Target(ElementType.FIELD)

public @interface BindView {

int

2、定义Processor派生自AbstractProcessor 并且使用@Auto

AutoService会自动在META-INF文件夹下生成Processor

就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载

3、提取注解信息

在Processor中提取注解信息 结合一些手段去处理,比如 JavaPoet ,或者 JavaPoet使用指南

核心点

处理Processor中的 注解信息的套路

2、AspectJ

简单介绍

AspectJ 是使用最为广泛的 AOP 实现方案,适用于 Java 平台,官网地址: www.即在编译期注入代码的 。

AspectJ 提供了一套全新的语法实现,完全兼容 Java(跟 Java 之间的区别,只是多了一些两种方式 :

使用 AspectJ 的语言进行

通过 AspectJ 提供的注解在 Java 语言上开发

因为最终的目的其实都是需要在

术语

JoinPoints(连接点)

JoinPoints(连接点),程序中可能作为代码注入目标的特定的点。在AspectJ中可以作为JoinPoints的地方包括

56561ab27f2c419a14c1b526d4696c4e.png

PointCuts(切入点)

PointCuts(切入点),其实就是代码注入的位置。与前面的JoinPoints不同的地方在于,其实PointCuts是有条件限定的JoinPoints。比如说,在一个Java源文件中,会有很多的JoinPoints,但是我们只希望对其中带有@de

Advice(通知)

Advice(通知),其实就是注入到class文件中的代码片。典型的 Advice 类型有 before、after 和 around ,分别表示在目标方法执行之前、执行后和完全替代目标方法执行的代码

Aspect(切面)

Aspect(切面),Pointcut 和 Advice 的组合看做切面。

Weaving

注入代码(advices)到目标位置(joint points)的过程

3、Javassit

简介

Javassist作用是在 编译器间修改class文件 ,与之相似的ASM(热修复框架女娲)也有这个功能,可以让我们直接修改编译后的class二进制代码,

首先我们得知道什么时候编译完成,并且我们要赶在class文件被转化为dex文件之前去修改。在Transfrom这个api出来之前,想要在项目被打包成dex之前对class进行操作,必须自定义一个T

fb1dfe3798693f33ad6da0da0f88d3c0.png

常用方式

需要配合自定义 GradlePlugin、TransForm,往往在TransForm期间使用Javassit 去完成一些需要的aop,关于自定义Gradle插件这里就不继续展开了

ClassPool、CtClass、CtMethod核心类的使用在这里展示的很详细。

1、初始化ClassPool设置 2、通过包名取到对应的CtClass 3、CtMethodi插入代码块,写文件,释放,结束整个注入代码过程。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐