前言
AOP(Aspect Oriented Programming)意为:面向切面编程。到底什么意思呢?我们来举个例子说明。
传统的OOP(Object Oriented Programming面向对象编程)系统中,各个模块之间是相互独立的,比如说某管理系统的模块图如下:
上图对于业务需求而言,需求和具体实现之间是一一对应的,无论从开发还是维护的角度,都比较方便。
不过,在开发中为例调试,或者进入生产环境后为了对系统进行监控,我们需要为这些业务实现添加日志记录功能;或者,业务方法的执行需要一定的权限限制,那么,方法执行前肯定要执行相应的安全检查功能。虽然需求都很明确(加入日志记录,加入安全检查等等),但是,系统中的每个业务对象都要加入这些功能的话,这些功能代码就会遍及所有的业务对象。如果每个业务对象前后都要加上这些需求,那么,会造成大量的冗余代码。
对于这类散落在系统各处的需求,需要借助于AOP的开发模式,它可以将这些需求(日志记录,安全检查,事务处理等)像一把把刀“横切”到我们已经组织好的各个业务功能模块上。如下图:
上图中的“红杠杠”就是“切面(Aspect)”。Aspect之于AOP,就相当于Class之于OOP。AOP仅仅是OOP方法的一种补充,当我们把以Class形式的业务模块,和以Aspect形式的系统需求拼装到一起,整个系统就算完整啦。
正文
spring提供了一整套完整的体系来支持AOP。其核心思想就是:代理!通过代理在业务对象前后加上功能代码。
一,了解AOP术语
1.target:目标类,需要被代理的类。例如:UserService
2.Joinpoint(连接点):所谓连接点是指那些可能被拦截到的方法。例如:所有的方法
3.PointCut 切入点:已经被增强的连接点。例如:addUser()
4.advice 通知/增强,增强代码。例如:after、before
5.Weaving(织入):是指把增强advice应用到目标对象target来创建新的代理对象proxy的过程.
6.proxy 代理类
7.Aspect(切面): 是切入点pointcut和通知advice的结合。
画图更清晰:
从上图看出,一个AOP过程就是一个代理的过程嘛。
二,AOP的3种实现方式
1,jdk的动态代理。了解,不常用。
编写目标类和增强类,然后写代理类。在目标类方法前后加上增强类的方法。
2,SpringAOP。了解,不常用。
编写目标类和增强类。然后将“代理关系”配置到xml文件中。
3,AspectJ实现AOP。重点,要掌握。
AspectJ是一个java语言实现的AOP框架。其中要掌握:“AOP的5种通知类型”和“切入点表达式”。
下面是一个简单举例,其中只用到了around类型的通知:
同样的,织入的过程仍然是一个“代理”的过程。
下面,我们来写一个测试类来获取目标类的对象,并调用对象中的方法。
package com.jimmy.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.jimmy.target.Target;
public class Test1 {
@Test
public void test1(){
String xmlpath = "applicationContext.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlpath);
Target target = (Target) applicationContext.getBean("targetId");
target.saySomething();
}
}
上面代码其实获取的是目标类对象的代理对象,其在目标类对象前后加了业务代码,结果如下:
before // 前处理
target function... // 目标函数
after // 后处理
总结
本文并没有关注AOP编码的细节,而是从总体上解释了AOP产生的动机和使用形式,具体使用要结合业务逻辑。