-
Android开发中的面向切面编程AOP
发布:51Code 时间: 2019-02-11 10:50
-
目录 有什么用 App中很多跳转的地方都需要登入校验,无非就是if-else,但是如果这样的判断有很多,我们就得重复很多次,或者有一天需求变动,有可能就会更改多个地方。类似的还有...
-
目录
有什么用
• App中很多跳转的地方都需要登入校验,无非就是if-else,但是如果这样的判断有很多,我们就得重复很多次,或者有一天需求变动,有可能就会更改多个地方。类似的还有网络判断,权限管理,Log日志的统一管理这样的问题,如果更优雅的实现这些功能呢?
• App 调试时,如果一眼无法看出错误在哪里,有时会把一些关键信息打印出来,如何快速将方法的入参和出参都打印出来?
• 如何安全地执行方法,不用考虑异常情况?
• …….
什么是AOP?
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
AOP 解决 OOP 中遇到的一些问题.是 对OOP 的延续和扩展
AOP中的术语
• Joinpoint(连接点):所谓连接点是指那些被拦截到的点。
• Pointcut(切入点):所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义。
• Advice(通知/增强):所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知。
• Introduction(引介):引介是一种特殊的通知在不修改类代码的前提下, Introduction 可以在运行期为类 动态地添加一些方法或 Field。
• Target(目标对象):代理的目标对象。
• Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程. AspectJ 采用编译期织入和类装在期织入 。
• Proxy(代理):一个类被 AOP 织入增强后,就产生一个结果代理类 。
• Aspect(切面):是切入点和通知(引介)的结合 。
Advice分类:
Android中如何使用AOP?
AspectJ 介绍
AspectJ是一个面向切面编程的框架。AspectJ是对java的扩展,而且是完全兼容java的,AspectJ定义了AOP语法,它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。AspectJ还支持原生的Java,只需要加上AspectJ提供的注解即可。在Android开发中,一般就用它提供的注解和一些简单的语法就可以实现绝大部分功能上的需求了。
下面通过一个例子来说明一下AOP中各个术语的含义:
假设UserDao 中的四个方法均已实现,现在需要对delete()方法加入权限校验。那么我们就需要对UserDao 这个类进行增强,那么UserDao这个类就是Target(目标对象),而该类中有四个方法,我们现在只对delete()方法进行改造,所以delete()就是Pointcut(切入点);其他方法都是Joinpoint(连接点);新增的权限校验方法就是Advice(通知);Introduction(引介)是对类方面的增强;将通知应用到目标的过程就是 Weaving(织入)
切入点表达式语法
语法如下:
切入点指示符([访问修饰符] 方法的返回值类型 包名.类名.方法名(参数))
AspectJ类型匹配的通配符:
切入点指示符
切入点指示符用来指示切入点表达式目的,AspectJ切入点指示符如下:
AspectJ切入点支持的切入点指示符还有: call、get、set、preinitialization、staticinitialization、initialization、handler、adviceexecution、withincode、cflow、cflowbelow、if、@this、@withincode。
切入点语法详细说明
Android 中使用Gradle集成 AspectJ
在Android中集成AspectJ,主要思想就是hook Apk打包过程,使用AspectJ提供的工具来编译.class文件。自己手动接入AspectJ的话,比较繁琐。目前有一些在Android中集成AspectJ的比较火的框架,如JakeWharton的 gradle_plugin_android_aspectjx。该框架支持kotlin。这里就使用该框架做演示,不再自己手动接入。
在项目根目录build.gradle下引入aspectjtools插件:
在module目录下的build.gradle中引入插件和依赖:(注释部分)
至此Aspectj的环境已经搭建好了,下面通过一个登入检查的例子来说明它如果使用。
1.创建Target(目标类)
@Retention(AnnotationRetention.RUNTIME)//存储在编译后的 Class 文件,反射可见。
@Target(AnnotationTarget.FUNCTION)//方法(不包括构造函数)
annotation class CheckLogin
这里创建的是一个注解,所有被该注解标识的方法都是接入点
关于Target和Retention参数的说明:
2.创建切面AspectJ
这是方便演示判断登入的方法省略直接用一个变量isLogin 来代替了,只要明白意思即可。
3.创建测试类
test方法被@CheckLogin修饰,会先判断是否登入,如果登入了就会执行text方法中的代码,上面我们模拟的是没有登入isLogin = false,所以程序的运行结果就是提示:请先登入,而不会执行test方法中的代码。这样在需要检测登入的操作方法上添加上@CheckLogin即可实现登入校验的操作,当登入校验的逻辑发生改变的时候,我们也不需要改动调用的地方。
当然我们可以使用通配符“*”对项目中所有的的某个方法进行增强操作。
总结
AOP是对OOP的扩展,OOP强调的是纵向的,而AOP是横向的,假如项目中有很多个删除的方法,现在都需要对删除方法加上校验的操作,一种是:定义一个基类,在基类中实现权限校验的功能,然后去集成它,这样所有用到的地方都得修改,继承就是纵向的;第二种就是利用AOP,使用代理对象,这样所有用到删除的方法是横向的,组成一个面。
文章来源:https://mp.weixin.qq.com/s/zc9zR23XX8VIVCbT0LcOXg上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8103),我们将立即处理。
了解51Code- Java 性能优化的 45 个细节 04月02日
- 10年Java老鸟忠告:技术人这4个错别再 04月02日
- 从华为的P40发布会看基于HTML5的web前端 03月27日
- Spring Boot 注解大全,真是太全了! 01月21日
- 代码对比工具,我就用这6个 01月19日
- 开发者必备的顶级Android开发工具 04月02日
- 这些小工具让你的Android开发更高效 01月21日
- 60个Android开发中要注意的细节 01月21日
- 2020 年需要关注的 5 大 Android 开发技术 01月17日
- 身处小公司如何在2年内快速突破拿到 01月02日
- Android 2018年九月面试经历总结 10月22日
- Android 彻底组件化—如何使用 Arouter 07月12日
- 工欲善其事,必先利其器,分享31个 07月04日
- 博为峰成立十五周年记02月15日
- 博为峰51Code推出“ACE计划”12月12日
- 博为峰51Code“全栈Java工程师”课程再03月01日
