AOP In Android (1)——初识入门

前言

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
——本段摘自百度百科

我的理解是,AOP(Aspect Oriented Programming)是和OOP(Object Oriented Programming)一个层面的概念。它首先是一种思想,一种基于OOP进化之后的思想,我们需要先了解到OOP中的一些不足,然后才有衍生出AOP的模式的依据。

一个经典的例子,日志输出。

假设我们有俩个模块,一个用户模块,一个首页模块,他们都需要进行日志输出。

  • 用OOP的角度来看,我们就需要find到日志模块来帮助我们打印日志。首先要有日志模块,然后再利用日志模块的函数分散的部署进我们需要打印日志的地方,按照邓神的说法,”耦合非常紧密。而且,将来要是日志模块修改了API,则使用它们的地方都得改。这种搞法,一点也不酷“。

  • 用AOP的角度来看,一个前提,首先我们要意识到到在OOP中的搞法”一点也不酷”,然后才有用AOP的动机,如果说,OOP如果是把问题划分到单个模块的话,那么AOP就是把涉及到众多模块的某一类问题进行统一管理。比如我们可以设计1个日志相关的Aspects。

  • 个人感觉,AOP相对于OOP的优点是,代码更有条理,逻辑更清晰,实现显得更优雅,但是,维护成本和学习成本也是有点高。可谓有利有弊吧。

理解:AOP术语。

本段部分内容引用自:http://www.jb51.net/article/128415.htm

  • Advice:通知

被归类,集中管理的功能,譬如上例中的日志输出。

  • JoinPoint:连接点

允许你通知(Advice)的地方,那可就真多了,基本每个方法的前、后(两者都有也行),或抛出异常是时都可以是连接点。AspectJ还可以让你在构造器或属性注入时都行,不过一般情况下不会这么做,只要记住,和方法有关的前前后后都是连接点

  • PointCut:切点

上面说的连接点的基础上,来定义切入点,你的一个类里,有15个方法,那就有十几个连接点了对吧,但是你并不想在所有方法附件都使用通知(使用叫织入,下面再说),你只是想让其中几个,在调用这几个方法之前、之后或者抛出异常时干点什么,那么就用切入点来定义这几个方法,让切点来筛选连接点,选中那几个你想要的方法。

实际上,连接点就是为了让你好理解切点搞出来的,可以将切点理解为被选中的连接点。

  • Aspect:切面

切面是通知和切入点的结合。现在发现了吧,没连接点什么事,连接点就是为了让你好理解切点搞出来的,明白这个概念就行了。通知说明了干什么和什么时候干(什么时候通过before,after,around等AOP注解就能知道),而切入点说明了在哪干(指定到底是哪个方法),这就是一个完整的切面定义。

  • weaving:织入

把切面应用到目标对象来创建新的代理对象的过程。

  • introduction:引入

引入感觉就像是一种抽象的行为,允许我们向现有的类添加新方法属性。这不就是把切面(也就是新方法属性:通知定义的)用到目标类中吗。

  • target:目标

引入中所提到的目标类,也就是要被通知的对象,也就是真正的业务逻辑,他可以在毫不知情的情况下,被咋们织入切面。而自己专注于业务本身的逻辑。

  • proxy:代理

AOP即是使用代理模式来实现的。

  • target Object:目标对象

项目原始的Java组件。

  • AOP代理

由AOP框架生成java对象。

  • AOP代理方法

advice + 目标对象的方法。

AspectJ in Android

AspectJ是Aop在android上一个较为靠谱的技术方案。AspectJ的编译工具叫做ajc,AspectJ有一套自己的语法。

本段部分内容引用自:https://www.jianshu.com/p/f90e04bcb326

语法

AspectJ的语法分为2个部分。

  • 声明的注解含义
  • 切点表达式

声明的注解含义:

  • @Pointcut(切点表达式):定义切点,标记方法
  • @Before(切点表达式):前置通知,切点之前执行
  • @Around(切点表达式):环绕通知,切点前后执行
  • @After(切点表达式):后置通知,切点之后执行
  • @AfterReturning(切点表达式):返回通知,切点方法返回结果之后执行
  • @AfterThrowing(切点表达式):异常通知,切点抛出异常时执行
  • @Aspect:声明切面,标记类
  • @Around(Pointcut):替代原来的代码,如果要执行原来的代码,需要使用ProceedingJoinPoint#proceed();注:不支持和@before,@after等一起使用

当然不止这些,具体参考:
https://github.com/hiphonezhu/Android-Demos/blob/master/AspectJDemo/AspectJ.pdf

备注: @Pointcut、@Before、@Around、@After、@AfterReturning、@AfterThrowing需要在切面类中使用,即在使用@Aspect的类中。

切点表达式

想要精通切点表达式,感觉花费的功夫应该会很大,目前作简单的练习,先学会走,再进阶跑。

基本原则:

execution(<修饰符模式>? <返回类型模式> <方法名模式>(<参数模式>) <异常模式>?)

贴几个示例来帮助理解。

  • 任意公共方法的执行:
execution(public * *(..))
  • 任何一个名字以“test”开始的方法的执行:
execution(* test*(..))
  • com.xyz.service.AccountService接口定义的任意方法的执行:
execution(* com.xyz.service.AccountService.*(..))
  • 在com.xyz.service包中定义的任意方法的执行:
execution(* com.xyz.service.*.*(..))
  • 在com.xyz.service包或其子包中定义的任意方法的执行:
execution(* com.xyz.service..*.*(..))

更多请参考:http://blog.csdn.net/dc_726/article/details/8565174

下一篇进行一个简单的实战

参考文章

浅谈Android面向切面编程(AOP)
https://www.jianshu.com/p/aa1112dbebc7

深入理解Android之AOP
http://blog.csdn.net/innost/article/details/49387395

使用AspectJ在Android中实现Aop
http://blog.csdn.net/crazy__chen/article/details/52014672

AOP 之 AspectJ 全面剖析 in Android
https://www.jianshu.com/p/f90e04bcb326

AspectJ风格的Aop切点表达式
http://blog.csdn.net/dc_726/article/details/8565174

你可能感兴趣的:(架构)