AOP简介

相信大家都很熟悉OOP(面向对象编程),AOP即是与之相对的另一种编程思想,即面向切面编程。AOP一般是使用了预编译生成代理类,或者是运行时动态代理的技术,实现了在尽量保持原有业务代码不变的情况下增加一些业务无关的功能或逻辑。例如;日志记录,性能统计,安全控制,事务处理,异常处理等。

与OOP的关系

按我们OOP单一职责原则思想进行设计,一般都会将这些模块封装成一个单一的类(比如Log)。而这种封装,虽然解决了代码的重用性,但还是没能解决这些模块的代码调用的重复分散且与业务代码耦合的现状。

最原始逻辑 和 OOP封装后的逻辑::

AOP与OOP并不是对立的,我们并不是为了代替OOP而提出AOP,AOP是OOP的延续和补充。当我们需要为分散的对象引入公共行为的时候,OOP则显得很无力,而AOP正是为解决这种问题而生的。

AOP的目标就是把这些功能集中并隔离起来,放到一个统一的地方来控制和管理。如果说,OOP如果是把问题划分到单个模块的话,那么AOP就是把涉及到众多模块的某一类问题收集起来进行统一管理。

AOP初窥

AOP在我们Android开发中并不多见,但在后端开发中却是有着重要的地位,就拿著名的Spring框架来说,其背后核心的两个点就是IoC(控制反转,依赖注入)和AOP。

我们来看个事务操作的例子。

下面这个是原生Android操作SQLite数据库时,开启事务的一般流程:

public  void  batchSave(Data data) {
    MySQLiteOpenHelper dbOpenHelper = new MySQLiteOpenHelper(context);
    SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
    //开启事务
    db.beginTransaction();
    try {
        //数据库操作1
        db.execSQL("SQL语句", data);
        //数据库操作2
        db.execSQL("SQL语句2",data);
        //设置事务标志为成功,当结束事务时就会提交事务
        db.setTransactionSuccessful();
    } catch(Exception e){
        throw(e);
    } finally {
        //结束事务
        db.endTransaction();
    }
}

在Spring中开启数据库的事务是怎样的呢:

...
@AutoWired
DataMapper mapper;
...

@Transaction
public  void  batchSave(Data data) {
    mapper.insert(data);
    mapper.update(data);
}

上面的例子我们看到,Spring把所有业务无关的代码全部都剔除了出去,只增加了两个注解。而这两个注解也正是Spring框架IoC和AOP核心两点的体现。必要的依赖通过了@AutoWired注解进行注入;事务开启、事务提交、异常处理和事务回滚等流程性的代码换成了一个 @Transaction注解。这里我们先不讲@Transaction的原理,在我们看完这篇AspectJ的介绍后你自然也就就知道Spring是怎么实现的了。

AspectJ语法基础

在介绍AspectJ之前我们先看下他的一些概念和术语: