AOP

AOP

面向切面编程,也可称为面向方面编程,是一种编程规范,提供从另一个角度来考虑程序结构从而完善面向对象编程(oop)

在进行oop开发时,都是基于对组件进行开发,然后对组件进行组合,oop最大问题就是无法解耦组件进行开发

AOP为开发者提供一种进行横切关注点,分离并织入的机制,把关横切关注点分离,然后织入到系统中,从而无耦合的完成了我们的功能

AOP能干什么:

  1. 用于横切关注点的分离和织入横切关注点到系统
  2. 完善oop
  3. 降低组件和模块之间的耦合性
  4. 使系统容易扩展
  5. 而且由于关注点分离从而可以获得组件的更好复用

关注点和织入

关注点可以分为核心关注点和横切关注点,核心关注点即一些主要业务流程,比如支付,横切关注点相当于一些服务,比如日志输出。

  1. 关注点

    可以认为是任何东西,比如日志组件

  2. 关注点分离

    将问题细化从而单独部分,既可以理解为不可再分割的组件。

  3. 横切关注点

    一个组件无法完成需要的功能,需要其他组件协助完成,如日志组件,横切于支付组件。

    横切关注点可能包含很多,比如非业务的:日志,事务处理,缓存,性能统计,权限控制等等这些非业务的基础功能,还可能是业务,如某个业务组件横切于多个模块

  4. 织入

    横切关注点分离后,需要通过某种技术将横切关注点融合到系统中从而完成需要的功能,因此需要织入,织入可能在编译期,加载期,运行期等进行。

AOP的基础概念

  1. 连接点(Joinpoint)

    表示需要在程序中插入横切关注点的扩展点,Spring只支持方法执行连接点,在AOP中表示“在哪里干”。

  2. 切入点(Pointcut)

    选择一组相关连接点的模式,即可以认为连接点的集合,Spring支持perl5正则表达式和Aspect切入点模式,Spring默认使用Aspect语法,在AOP中表示“在哪里干的集合”

  3. 通知(Advice)

    在连接点上执行的行为,通知提供了在AOP中需要在切入点所选择的连接点处进行扩展现有行为的手段,包括前置通知(before advice),后置通知(after advice),环绕通知(around advice),在AOP中表示为“干什么”

  4. 方面/切面(Aspect)

    横切关注点的模块化,在AOP中表示为“在哪干和干什么集合”

    切面=切入点+通知

  5. 目标对象(Target Object)

    需要被织入横切关注点的对象,在AOP中表示为“对谁干”

  6. 织入(Weaving)

    织入是一个过程,是将切面应用到目标对象从而创建出AOP代理对象的过程,织入可以在编译期,类装载期,运行期进行。

    1. AOP代理(AOP Proxy)

      AOP框架使用代理模式创建的对象,从而实现在连接点处插入通知(即应用切面),就是通过代理来对目标对象应用切面。在Spring中,AOP代理可以用JDK动态代理或CGLIB代理实现,而通过拦截器模型应用到切面。

  7. Advice分类
    前置通知(Before Advice):在切入点选择的连接点处的方法之前执行的通知
    后置通知(After Advice): 在切入点选择的连接点处的方法之后执行的通知
    环绕通知(Around Advices):环绕着在切入点选择的连接点处的方法所执行的通知

  8. execution表达式

    execution表达式是切入点(PointCut)中使用的一种模式,比如

    execution(* com.sample.service.impl..*.*(..))
    

    第一个号:表示返回类型,号表示所有的类型。
    包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.sample.service.impl包、子孙包下所有类的方法。
    第二个号:表示类名,号表示所有的类。
    (..):最后这个星号表示方法名,号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。

    示例:

    定义业务类

AOP_第1张图片

​ 定义切面
AOP_第2张图片

​ 配置

AOP_第3张图片
AOP_第4张图片

测试

AOP_第5张图片

@Aspect

Spring除了支持Schema方式配置AOP,还支持注解方式:使用@AspectJ风格的切面声明
启用对@Aspect的支持声明切面,@Aspect声明切入点org.aspectj.lang.annotation包下的,@Pointcut(value=“execution表达式”)。

声明通知
org.aspectj.lang.annotation 包下的
@Before(value = "切入点表达式或命名切入点")
@After(value = "切入点表达式或命名切入点")
@Around(value = "切入点表达式或命名切入点")

示例:

定义业务类

AOP_第6张图片

定义切面
AOP_第7张图片

配置

AOP_第8张图片

测试
AOP_第9张图片

你可能感兴趣的:(AOP)