动机和基本概念

AOP
并不是一种新的技术或者新的思想,早在60年代的程序员用模块化编程的时候就开始了这样程序思想。通过将不同的关注封装在不同的模块中来实现关注分离的目的。我们的程序中有些(方面)的代码是分离的或者缠结在一起的,这使得这些代码难以理解和维护。当一个关注(concern)(比如 记录日志)被分散在很多模块中的时候(比如类和方法),代码是分离的,这意味着改变日志记录需要更改所有受影响的模块。
例如,考虑如下的银行应用中非常简单易懂的,用于从一个账户向另一个账户转账的方法代码:
void transfer(Account fromAccount, Account toAccount, int amount)
{
  if (fromAccount.getBalance() < amount)

 {
    throw new InsufficientFundsException();

  }
  fromAccount.withdraw(amount);//
从一个帐户提款。
  toAccount.deposit(amount);
 //向另一个帐户存款。
}

但是,上面的代码对于现实中的银行应用还远远不够。现实银行应用需要校验当前用户是否有权限执行这个操作的安全性检查。操作应当在数据库事务中进行以防止数据的意外丢失。为了便于诊断系统中出现的问题,这些操作还应当被记录到系统日志中。诸如此类。带有所有这些新关注的代码的简单版本如下:

void transfer(Account fromAccount, Account toAccount, int amount)

{

   if (!getCurrentUser().canPerform(OP_TRANSFER))
   {
    throw new SecurityException();
   }
   if (amount < 0)
   {
    throw new NegativeTransferException();
   }

  if (fromAccount.getBalance() < amount)
  {
    throw new InsufficientFundsException();
  }

  Transaction tx = database.newTransaction();
  try

 {
     fromAccount.withdraw(amount);

     toAccount.deposit(amount);

     tx.commit();

     systemLog.logOperation(OP_TRANSFER, fromAccount, toAccount, amount);

   }

   catch(Exception e)
   {
     tx.rollback();
     throw e;
   }
}

上面的代码因为新的不同的关注已经同基本的功能(有时候称为业务逻辑关注)缠结在一起,所以已经丧失了优雅性和简单性。事务,安全性和日志记录示范了什么是横切关注(cross-cutting concerns)。
考虑到如果突然需要改变的时候,(例如)应用关于安全性的考虑。在程序的当前版本中,安全相关的操作分散在跨越多个模块的代码中,如果发生变化会产生很大影响。
因此,我们发现横切关注没有被正确地封装在它们自己的模块中。这增加了系统的复杂性,并且使系统的升级变得相当困难。
AOP
试图通过让编程者在单独的被称之为切面(aspects的模块中表示横切关注来解决这个问题。切面包含通知(advice,被连接到程序中特定点的代码)和内部类型声明(增加到其他类中的结构性成员)。例如,安全模块可以包含在访问银行账户访问之前来执行安全检查的通知(advice)。切入点(pointcut)定义了连接点银行帐户被访问的时机(连接点,join points),而通知体中的代码定义安全保护如何被实现。这样,检查和替换可以在一个地方维护。进一步讲,一个好的切入点可以参与后续的程序变化,因此如果一个开发者创建了一个新的用于访问银行账户的方法,那么通知可以在执行时被用于这个新建的方法。
连接点(join points:在计算机科学中,连接点是连接程序中控制流程(control flow的点。在面向方面的编程中,一系列的连接点集合被描述为切入点。连接点是主程序和方面的相会之处。在面向对象语言中,连接点是程序执行中定义良好的点。这些点包括方法和构造函数的调用、字段访问以等等内容
切入点(pointcut:在面向方面计算机编程中,切入点是一系列连接点的集合。当程序执行到切入点所描述的其中一个连接点时,与这个切入点相关的代码片(被称为通知)就会被执行。这就使得一个程序员可以描述何处以及何时在已定义的行为之外去执行附加的代码。这样就能向已经存在的软件增加新的方面(aspects,或者是软件的设计带有清晰的关注分离(separation of concerns的特点,从而使编程者将不同的方面融入到一个完整的应用中。
通知(advice: 在面向方面计算机编程中,一片通知描述用于应用于程序中给定连接点的一个函数(function)、方法(method)和过程(procedure)

连接点模型(Join point models

面向方面语言中与通知相关的组件定义了一个连接点模型(join point model-JPM),JPM定义了三件事情:

何时(advice)通知可以运行。之所以叫连接点(join points)是因为它们是正在运行程序中那些附加行为可以被有效接入的点。为了使之可用,连接点需要被普通程序员所表达和理解。(为了使应用的某个方面在跨越不连贯的变化时保持稳定,连接点应当在跨越这些变化时稳定
一种指定(或者量化)连接点的方法,称之为切入点。切入点决定一个给定的连接点是否匹配。大多数有效的切入点语言使用类似基础语言的语法(例如,AspectJ 使用java符号),并且允许通过命名和组合来实现(切入点)重用(reuse)。
一种指定代码在连接点处运行的方法。AspectJ中,被称为通知(advice,并且能够在连接点之前、之后或者包围连接点运行。

AOP 编程的适用领域


Authentication
权限
Caching
缓存
Context passing
内容传递
Error handling
错误处理
Lazy loading
 懒加载
Debugging
  调试
logging, tracing, profiling and monitoring
 记录跟踪 优化 校准
Performance optimization
 性能优化
Persistence
  持久化
Resource pooling
 资源池
Synchronization
 同步
Transactions
事务