AOP面向切面编程

Posted *^O^*—*^O^*

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AOP面向切面编程相关的知识,希望对你有一定的参考价值。

概念

AOP(Aspect Oriented Programming)称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等等。
AOP利用一种称为"横切"的技术,将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。
使用"横切"技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。
横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事物。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。

应用场景:

某个分层的类中,满足一定规则的方法,都需要加入统一业务处理时,就可以使用日志,事务,权限,

对以上统一业务来说,常见的切面业务如:

  1. 响应统一的数据格式
  2. 统一异常处理
  3. 统一日志记录,如跟踪用户访问信息
  4. 用户统一会话管理、权限管理
  5. 方法执行时间计算
  6. 事务管理
  7. 其他
    优点:横切代码和纵切代码解耦,提高了扩展性,可维护性

实现方式/原理

**关键词:**
需要不修改任何原始代码,而进行代码方法增强

1) 原始类/被代理类
2) 代理类,实际使用时,不使用被代理类,而使用代理类
静态代理设计模式:
实现方式:(1)继承 (2)接口
动态代理:
原理:在运行时,通过一些技术手段(jdk提供的api,第三方框架等),动态的生成代理类(将被代理类/原始类以继承或者接口的方式,生成代理类)
了解:生成代理类的字节码二进制数据,再执行类加载,再基于一些技术手段,生成示例对象

实现方式(面试中,如果是先问了一堆Spring的知识,然后在问AOP,一般就只回答Spring AOP)
Spring 中AOP的实现,回答只需要回答Spring中动态代理的内容
1) JDK实现(接口的方式生成代理类:被代理类必须实现某个接口)
结合InvocationHandler+Proxy.newProxyInstance,以接口的方式生成代理类
2) CGLIB实现(继承的方式生成代理类:被代理类不能是final修饰)
结合MethodInterceptor,继承方式实现
动态代理框架,框架本身基于ASM字节码框架实现

补充:Spring中的拦截器有两种:

一种是HandlerInterceptor,专门做请求映射方法的拦截器(不是动态代理的实现)
一种是MethodInterceptor,以动态代理方式,对符合某个规则的方法进行增强,继承的方式,运行时,生成代理类(在被代理类方法前加入前置逻辑,方法后加入后置逻辑)

名词注解

切面(@Aspect)整个横切业务的抽象概念
切点(@Pointcut)在Spring AOP中,只有对方法进行织入,要在纵向业务代码的某处,加入要横切执行的统一业务
切点可以配置方法匹配规则,匹配别的方法,就会织入横切代码
通知(Advice)
表示横切的业务(横切代码)及何时执行横切代码(通知,目标方法在那个位置执行横切业务)
@AspectJ 支持三种通配符

  • :匹配任意字符,只匹配一个元素(包,类,或方法,方法参数)
    … :匹配任意字符,可以匹配多个元素 ,在表示类时,必须和 * 联合使用。
  • :表示按照类型匹配指定类的所有类,必须跟在类名后面,如 com.cad.Car+ ,表示继承该类的所有子类包括本身

通知

切面也是有目标的 ——它必须完成的工作。在AOP术语中,切面的工作被称之为通知。
通知:定义了切面是什么,何时使用,其描述了切面要完成的工作,还解决何时执行这个工作的问题。
Spring切面类中,可以在方法上使用以下注解,会设置方法为通知方法,在满足条件后会通知本方法进行调用:

前置通知
使用@Before:通知方法会在目标方法调用之前执行。
后置通知
使用@After:通知方法会在目标方法返回或者抛出异常后调用。
返回之后通知
使用@AfterReturning:通知方法会在目标方法返回后调用。
抛异常后通知
使用@AfterThrowing:通知方法会在目标方法抛出异常后调用。
环绕通知
使用@Around:通知包裹了被通知的方法,在被通知的方法通知之前和调用之后执行自定义的行为。

织入(Weaving)

织入是把切面应用到目标对象并创建新的代理对象的过程,切面在指定的连接点被织入到目标对象中。
在目标对象的生命周期里有多个点可以进行织入:

编译期:

切面在目标类编译时被织入。这种方式需要特殊的编译器。AspectJ的织入编译器就是以这种方式
织入切面的。

类加载期:

切面在目标类加载到JVM时被织入。这种方式需要特殊的类加载器(ClassLoader),它可以在目标类被引入应用之前增强该目标类的字节码。AspectJ5的加载时织入(load-time weaving. LTW)就支持以这种方式织入切面。

运行期:

切面在应用运行的某一时刻被织入。一般情况下,在织入切面时,AOP容器会为目标对象动态创建一个代理对象。SpringAOP就是以这种方式织入切面的。

以上是关于AOP面向切面编程的主要内容,如果未能解决你的问题,请参考以下文章

什么是面向切面编程

三面向切面编程

AOP面向切面编程(个人笔记1.1)

Spring的AOP面向切面编程

AOP 面向切面编程

Spring-AOP面向切面编程