美文网首页
Spring_AOP_01——概念讲解

Spring_AOP_01——概念讲解

作者: _Zy | 来源:发表于2018-06-05 19:40 被阅读47次

该文主要讲Spring AOP的一些概念,不会细讲如何使用AOP。
关于AOP的使用,可以参考文末链接。

AOP 概述

AOP是Spring框架的另一个基本组成部分。这一次我们就探讨一下Spring的这一重要特性。面向切面(Aspect Oriented Programming)

需要明确的是,AOP并不是Spring独有,AspectJ也实现了AOP的功能。AOP和OOP一样,是一种编程范式。而Spring实现的AOP功能比较经典。

实现AOP使用的是代理模式。通过对需要切入类的包装和增强,创建代理类。从而实现切入到执行过程中的作用。

代理主要分为两种方式:

  • 静态代理,基本的代理方式,AspectJ使用。
  • 动态代理,Spring使用的代理方式,使用了JDK和CGLIB的代理方式。

具体的代理实现AOP的原理,在下一期细讲。

什么是AOP?
AOP(Aspect Oriented Programming)面向切面编程,可以说是OOP(Object Oriented Programming)面向对象编程的补充和完善。

具体来说,AOP是通过 预编译方式运行时的动态代理 实现程序功能的统一维护的一种技术。AOP是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。

为什么要用AOP?
随着开发的系统越来越复杂,传统OOP程序会出现一些不自然的现象。核心业务中总掺杂一些不相关的业务。例如:日志记录,权限验证,事务控制,性能检测等等。这些功能模块可以说跟核心业务并无关系,而且核心业务也不关心他们。

这些场景就是一些分散的对象,涉及到了公共的行为。OOP在这方面显得无能为力。
这里要说一下,虽然可以使用继承来对公共行为做抽象,但是继承是一个纵向的关系,并且是强耦合的一种方式。有时候子类并不需要这个行为,而在很多情况下,需要这样行为的类之间根本就毫无关系。
如果非要使用这种方式,不仅会导致大量的重复代码,维护起来也是相当麻烦的一件事情,一点都不优雅。

而AOP引入了一种 "横切" 的技术,它是一种横向的关系。AOP使得我们可以把一些公共行为抽离出来,并且把这些行为,横向地插入到业务代码执行的过程中间。所以称之为 切面(Aspect)
这些横切进去的行为与具体业务无关,又嵌入到了业务模块的执行逻辑流程中,共同封装起来。便于减少重复代码,也降低了耦合度。利于系统的扩展性和可维护性。

可以用一张图简单的说明AOP的作用

AOP

AOP的功能

  • 用于横切关注点的分离 和 织入横切关注点到系统。例如日志,权限等
  • 对OOP的完善
  • 降低组件和模块之间的耦合性
  • 使得系统更易于扩展
  • 分离关注点可以获得组件更好的复用

AOP的使用场景

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

AOP 核心概念

切面(Aspect)
切面是一个关注点,或者说希望抽象出来的功能 的模块化。这个关注点或者功能可以横切多个对象。对应代码中,就是声明出来切面的类和其中的所有逻辑。

连接点(JoinPoint)
连接点是指在程序中某个特定的点,通过这个点来和切面建立连接,将切面的功能组合进去。他表示了可以组合 Advice 的位置。
也就连接点,是允许你执行通知的地方。在Spring中允许的通知有五种(接下来讲)。AspectJ还允许在构造器和属性注入时执行通知。
简单来说,在Spring中,方法的前前后后都是连接点,

通知(Advice)
通知是在切面上某个连接点上执行的特定操作。也就是我们抽离出来公共功能代码的逻辑部分。Spring切面中支持五种通知:

  • 前置通知(Before)在目标方法,或者说切点被调用前执行的通知。
  • 后置通知(After)在切点被调用后执行。
  • 返回通知(After-returning)在切点执行成功并返回以后执行
  • 异常通知(After-throwing)在方法抛出异常之后执行
  • 环绕通知(Around)包围一个连接点,在被通知的方法之前和之后执行。(内部调用 proceed() 来执行通知方法)

关于通知的执行优先级。
在不同的切面中,如果有多个通知需要在同一个切点函数指定的方法上执行,那么将会按照在代码中定义的顺序依次执行。

切点(PointCut)
简单来说,切点是匹配连接点的表达式或者说断言。
在上面切面概念的基础上,我们知道,方法的前后都可以是连接点,但我们并不希望在所有这些地方都执行通知,我们需要一个自己定义执行通知的地方。也就是切点。
通过切点的定义,就是让我们可以筛选出我们想要拦截的方法。

引入(Introduction)
在不修改代码的前提下,引入可以在 运行期 动态地为类添加一些方法或者字段。
也就是把切面应用到目标类中。

目标对象(Target Object)
引入中提到的目标类,也就是被通知的对象(具体的业务逻辑)。
目标对象可以在不关心切面的情况下被引入切面的新功能,实现了功能的解耦。

AOP代理(AOP Proxy)
AOP代理指AOP框架创建的,对象和切面的契约,也可以说是切面实现的方式。
事实上,一般AOP是通过代理的方式实现的。(代理又分为静态代理和动态代理,Spring使用的是动态代理)
AOP代理的目的,就是将切面织入到目标对象。

织入(Wearving)
把切面应用到目标对象,来创建代理对象的过程。Spring采用的是运行时织入,具体有两种方式JDK和CGLIB。AspectJ采用的是编译期织入。(这个下一期AOP原理分析时细讲)

以下是Spring使用注解方式实现AOP的简单例子(当然还可以使用xml配置的方式实现AOP)

使用Spring的AOP支持需要引入Spring-aspect的包,如果要启用注解支持,还需要添加AspectJ类库。

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>5.0.1.RELEASE</version>
    </dependency>

    <!-- aspectJ -->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.8.10</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.10</version>
    </dependency>

/**
 * @Author Antony
 * @Since 2017/11/30 16:35
 */
@Aspect
@Component
public class SychLockAspect {    //该类就是切面

    private static final Logger logger = LoggerFactory.getLogger(SychLockAspect.class);

    @Pointcut("execution (* com.antony.service.*.*(..))")    //这是切点表达式
    public void SychLockMethod(){}  //该方法体就是通知,内部是通知的逻辑,同时可以有before after , around 等 5种通知动作。

    @Before(value = "SychLockMethod()")
    public void beforeAspect(JoinPoint joinPoint){
        String sychKey = getSychKey(joinPoint);
        logger.info("sychKey={}", sychKey);
        logger.info("AspectBefore......");

    }


    @After(value = "SychLockMethod()")
    public void afterAspect(JoinPoint joinPoint){
        String sychKey = getSychKey(joinPoint);
        logger.info("sychKey={}", sychKey);
        logger.info("AspectAfter......");
    }


    @Around(value = "SychLockMethod()")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("Around before...");
        proceedingJoinPoint.proceed();
        System.out.println("Around After...");
    }
}

Spring AOP 的支持

Spring中的AOP代理,由Spring IOC 容器负责生成和管理。其依赖关系也由IOC容器负责管理。AOP代理可以直接使用容器中的其他Bean实例作为目标,这种关系可以由IOC容器的依赖注入提供。

Spring 默认使用JDK动态代理来创建AOP代理类。Spring目前仅支持将方法调用作为连接点(JoinPoint),如果需要把堆成员变量的访问和更新页作为增强处理的连接点,则可以考虑使用AspectJ。

Spring侧重于AOP实现和IOC容器之间的整合。

Spring 框架对AOP的使用
Spring 事务处理
SpringMVC(例如@ControllerAdvice)
Spring Security
(由于对Spring的各个功能模块都还没有完整的了解,目前已知的是这些,应该还有更多,后续补充)



(如果有什么错误或者建议,欢迎留言指出)
(本文内容是对各个知识点的转载整理,用于个人技术沉淀,以及大家学习交流用)


参考资料:
关于SpringAOP你该知晓的一切
Spring之AOP-简书(主要是AOP基本概念和如何使用AOP)
AOP低层实现——JDK和CGLIB的动态代理

相关文章

  • Spring_AOP_01——概念讲解

    该文主要讲Spring AOP的一些概念,不会细讲如何使用AOP。关于AOP的使用,可以参考文末链接。 AOP 概...

  • 概念讲解之前传-因为没有,所以需要

    部分拆书家认为概念讲解很容易;部分拆书家认为概念讲解很难。我认为真正的概念讲解能力不容易练成。说容易的,估计大多是...

  • 讲解AOP相关概念

    Crocss Cutting Concern(横切性的关注点)— 是一种独立服务。遍布在系统的各个角落里,或者是处...

  • gradle常见概念讲解

    1、Gradle 项目的构建工具,管理一个项目的依赖架包,性质和maven相似 一个基于groovy的项目打包工具...

  • 概念讲解问题思考

    笔记思维,最近在整理笔记思维的时候,发现讲述的过程中存在一定的问题,脑子里会有一些东西,不过要讲个一个新人来听,还...

  • OpenGL相关概念讲解

    OpenGL(Open Graphics Library)是一个跨编程语言、跨平台的图形应用程序编程接口。他将计算...

  • Golang Gist

    概念讲解 基础概念 基础问答 基础问答 编码能力考查x

  • 太德财创 区块链创业史

    今天给大家讲解了永存链的概念。

  • Maven核心概念全讲解

    Maven 是什么? Maven的意思是“专家,知识的积累着”,来自Yiddish语言,meyvn单词,意为“知识...

  • MyBatis四大核心概念

    本文讲解 MyBatis 四大核心概念(SqlSessionFactoryBuilder、SqlSessionFa...

网友评论

      本文标题:Spring_AOP_01——概念讲解

      本文链接:https://www.haomeiwen.com/subject/hijmsftx.html