图文并茂!!!一文搞懂springaop(面向切面编程)(代码片段)

月下赶路人 月下赶路人     2022-12-14     702

关键词:

文章目录

SpringAOP

我们为什么要使用AOP(面向切面编程)?当我们在现实中完成实际的项目时,我们总是需要在一个“动作”进行前,进行中,或进行后进行一些操作,比如当我们在运行程序时,我们想要进行日志保存,或者在每一个方法调用后输出一句话,这就表示我们每一次进行一个“动作”都需要进行同样的操作,这就导致程序员会进行大量的、无用的重复性动作,面对这种情况,AOP应运而生。

AOP概述

AOP,即Aspect Oriented Rrogramming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能统一维护的一种技术。AOP可以对业务漏极的各个部分进行隔离,从而使得业务逻辑之间得耦合性降低,提高程序得可重用性,同时提高了开发得效率。

AOP和OOP是两种不同的设计思想。OOP(面向对象编程)针对业务处理过程得实体及其属性和行为进行抽象封装,获得清晰高效得逻辑单元划分。AOP则是针对业务处理过程中得切面进行提取,是面对业务处理过程中的某个步骤或阶段,获得逻辑过程中各部分之间低耦合性得隔离效果。

面向切面编程的好处就是:减少重复,专注业务。它是面向对象编程的一种补充。

核心原理及使用案例

原理:使用动态代理的方式在执行方法前后或出现异常时加入相关的逻辑。

使用:

事务处理:开启事务,关闭事务,出现异常回滚事务.....
权限判断:执行方法前,判断是否具有权限;
日志处理;
......

AOP的基本概念(Spring的专业术语)

0.增强:向各个程序内部注入一些逻辑代码从而增强原有程序的功能。

1.连接点(JoinPoint):类中可以被增强的方法,这个方法就就被称为连接点,切记连接点并不是一定会被增强。

2.切入点(Pointcut):类中实际被增强的方法。

3.通知(Advice):指一个切面在特定的连接点要做的事情,简单来说就是“增强”。可以分为方法执行前通知,方法执行后通知,环绕通知等等。

4.切面(Aspect):把通知添加到切入点的过程就叫切面。

5.目标(Target):代理的目标对象,即要增强的方法所在的类。

6.代理(Proxy):向目标对象应用通知之后创建的代理对象。

SpringAOP实现

很多的框架都对AOP这种编程思想进行了实现。Spring只是其中的一种,可以完成面向切面编程。AspectJ也是一个面向切面的框架,并且实现方式更为简捷,更为方便,并且支持注解式开发。所以,Spring又将AspectJ对于AOP的实现引入到自己的框架之中。

Spring中使用AOP开发时,通常使用AspectJ的实现方式。其中常用的通知有五种类型:

前置通知:方法执行前执行;
后置通知:方法执行后执行;
环绕通知:前后都执行;
异常通知:出异常时通知;
最终通知:如return后执行。

SpringAOP的使用

导入实现AOP的AspectJ的jar
<!--Spring实现AOP是依靠Aspects框架实现-->
<!--Aspects相关jar-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.2.2.RELEASE</version>
</dependency>
基于AspectJ的xml配置实现

所有的配置都在spring.xml文件中进行。

1.创建一个增强功能的类。

import org.aspectj.lang.ProceedingJoinPoint;
//通知(Advice):在连接点要做的事情
public class Aop 

    public void doLog() 
        System.out.println("=====保存日志=====");
    

    public void commit() 
        System.out.println("=====提交事务=====");
    

    public void around(ProceedingJoinPoint proceedingJoinPoint) 
        System.out.println("======方法前通知======");
        try 
            proceedingJoinPoint.proceed();//调用自己的方法
         catch (Throwable throwable) 
            throwable.printStackTrace();
        
        System.out.println("======方法后通知======");
    

    public void throwable(Throwable throwable) 
        System.out.println("======出异常了======");
        System.out.println(throwable.getMessage());
    

2.将装有增强功能的类交给交由spring管理

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!--把装有通知(Advice)的类交给Spring管理-->
    <bean id="aop" class="com.cwd.spring4pro.demo1.aop.Aop"></bean>
    
    <!--在这里进行织入,即切面(Aspect):将通知添加到切入点-->

</beans>

3.配置切面(Aspect)

先准备一个被增强的类,即目标(Target)

import org.springframework.stereotype.Component;

//目标(Target):代理的目标对象,即要增强的类
@Component(value = "target")
public class Target 
    /*
    连接点(Joinpoint),可以被增强的方法
    切入点(pointcut),实际被增强的方法,被增强了
    */
    public void pointCut() 
        System.out.println("这是一个保存的操作!!!");
        return;
    

将通知添加到切入点。

<!--织入-->
    <aop:config>
        <!--
        配置切入点 
        execution表达式 前*表示返回值 saveUser(..)表示要增强的方法 ..表示参数
        -->
        
        <aop:pointcut id="pointCut" expression="execution(* com.cwd.spring4pro.demo.Target.pointCut(..))"/>

        <!--配置通知 ref中引用的是通知类的id-->
        <aop:aspect ref="aop">
        
           <!--前置通知-->
           <aop:before method="doLog" pointcut-ref="pointCut"/>

        </aop:aspect>
    </aop:config>

五种通知类型配置

1.前置通知

<!--织入-->
<aop:config>
    <aop:pointcut id="pointCut" expression="execution(* com.cwd.spring4pro.demo.Target.pointCut(..))"/>
    <aop:aspect ref="aop">
        <!--前置通知-->
        <aop:before method="doLog" pointcut-ref="pointCut"/>
    </aop:aspect>
</aop:config>

2.后置通知

<!--织入-->
<aop:config>
    <aop:pointcut id="pointCut" expression="execution(* com.cwd.spring4pro.demo.Target.pointCut(..))"/>
    <aop:aspect ref="aop">
        <!--后置通知-->
        <aop:after method="commit" pointcut-ref="pointCut"/>
    </aop:aspect>
</aop:config>

3.环绕通知

<!--织入-->
<aop:config>
    <aop:pointcut id="pointCut" expression="execution(* com.cwd.spring4pro.demo.Target.pointCut(..))"/>
    <aop:aspect ref="aop">
        <!--环绕通知-->
        <aop:around method="around" pointcut-ref="pointCut"/>
    </aop:aspect>
</aop:config>

4.异常通知

修改一下pointCut

public void pointCut() 
    System.out.println("这是一个保存的操作!!!");
    int a = 10 / 0;
    return;

<!--织入-->
<aop:config>
    <aop:pointcut id="pointCut" expression="execution(* com.cwd.spring4pro.demo.Target.pointCut(..))"/>
    <aop:aspect ref="aop">
        <!--异常通知-->
        <aop:after-throwing method="throwable" pointcut-ref="pointCut" throwing="throwable"/>
    </aop:aspect>
</aop:config>

5.最终通知

<!--织入-->
<aop:config>
    <aop:pointcut id="pointCut" expression="execution(* com.cwd.spring4pro.demo.Target.pointCut(..))"/>
    <aop:aspect ref="aop">
        <!--最终通知-->
        <aop:after-returning method="commit" pointcut-ref="pointCut"/>
    </aop:aspect>
</aop:config>

最终通知一般在return之后执行。

注解实现

开启aop注解扫描

<!--开启注解标签-->
<aop:aspectj-autoproxy/>

在通知类中进行配置,如下所示:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component//将这个类交给Spring管理
@Aspect//标注这个类时装有通知的类
public class Aop 

    @Before("execution(* com.cwd.spring4pro.demo.Target.pointCut(..))")
    public void doLog() 
        System.out.println("=====保存日志=====");
    

    @After("execution(* com.cwd.spring4pro.demo.Target.pointCut(..))")
    public void commit() 
        System.out.println("=====提交事务=====");
    

    public void around(ProceedingJoinPoint proceedingJoinPoint) 
        System.out.println("======方法前通知======");
        try 
            proceedingJoinPoint.proceed();//调用自己的方法
         catch (Throwable throwable) 
            throwable.printStackTrace();
        
        System.out.println("======方法后通知======");
    


    @AfterThrowing(value = "execution(* com.cwd.spring4pro.demo.Target.pointCut(..))",throwing = "throwable")
    public void throwable(Throwable throwable) 
        System.out.println("======出异常了======");
        System.out.println(throwable.getMessage());
    

    @AfterReturning("execution(* com.cwd.spring4pro.demo.Target.pointCut(..))")
    public  void returnAfter() 
        System.out.println("======return后=====");
    

从源码入手,一文带你读懂springaop面向切面编程

之前《零基础带你看Spring源码——IOC控制反转》详细讲了Spring容器的初始化和加载的原理,后面《你真的完全了解Java动态代理吗?看这篇就够了》介绍了下JDK的动态代理。基于这两者的实现上,这次来探索下Spring的AOP原理。虽... 查看详情

一文搞懂springaop源码底层原理

...落到代码的各个部分,难以维护。一键获取源码地址springaop面试题AOP就是把这些问题和主业务逻辑分开,达到与主业务逻辑解耦的目的。二、AOP的应用场景·日志记录·权限验证·效率检查·事务管理三、SpringAOP原理及其 查看详情

一文带你认识springaop(代码片段)

SpringAOP简介AOP(Aspect-OrientedProgramming:面向切面编程)是对OOP(Object-OrientedProgramming:面向对象编程)的补充和完善。OOP引入封装、继承和多态等概念来建立一种对象层次结构,用于模拟公共行为的一个集合。封装就要求将功能分散到... 查看详情

一文带你搞定aop切面(代码片段)

摘要:AOP在spring中又叫“面向切面编程”,是对传统我们面向对象编程的一个补充,主要操作对象就是“切面”,可以简单的理解它是贯穿于方法之中,在方法执行前、执行时、执行后、返回值后、异常后要... 查看详情

springaop面向切面编程

Spring中三大核心思想之一AOP(面向切面编程):在软件业,AOP为AspectOrientedProgramming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热... 查看详情

springaop面向切面编程的实现

1、涉及到的几个概念  切面类、被切对象、切入点、切入时间、切入内容;(自己命的名,好理解点)2、看配置文件<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSch... 查看详情

springaop面向切面编程--准备工作(代码片段)

引言1.创建一个SomeService接口类publicinterfaceSomeServicevoiddoSome();voiddoOther();2.创建一个SomeService接口类的实现类SomeServiceImpl选择对目录👇publicclassSomeServiceImplimplementsSomeService@Overridepublicvoi 查看详情

springaop面向切面编程3种实现方式

AOP面向切面编程什么是AOPAOP(AspectOrientedProgramming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是... 查看详情

springaop

SpringAOPSpringAOP(面向切面编程)SpringAOP(面向切面编程)AOP的全称是“AspectOrientedProgramming”,即面向切面编程,和OOP(面向对象编程)类似,也是一种编程思想。AOP采取横向抽取机制(动态... 查看详情

springaop面向切面编程-后置通知

总结:Aspectj表示切面执行时间,用的通知(Advice)。这个通知可以使用注解表示。5个注解表示切面的5个执行时间,这些注解叫做通知注解。@Before:前置通知@AfterRetunring:后置通知@Around:环绕... 查看详情

springaop

SpringAOPSpringAOP(面向切面编程)SpringAOP(面向切面编程)AOP的全称是“AspectOrientedProgramming”,即面向切面编程,和OOP(面向对象编程)类似,也是一种编程思想。AOP采取横向抽取机制(动态... 查看详情

:springaop面向切面编程

🙊🙊作者主页:🔗求不脱发的博客📔📔精选专栏:🔗SSM直击大厂📋📋精彩摘要:Spring AOP面向切面编程是JavaOOP面向对象编程的延续,是软件开发中的一个热点,也是Spring框... 查看详情

springaop面向切面编程,监听某个方法(代码片段)

1、单独监听某一个方法,方法的参数名称必须与args定义的参数名称一致@AfterReturning(pointcut="execution(*com.gmall88.server.manager.superapp.SuperAppServerManager.notifyRefund(..))&&args(notifyUrl,refundId,batchNo,callResult) 查看详情

springaop——spring中面向切面编程(代码片段)

前面两篇文章记录了SpringIOC的相关知识,本文记录Spring中的另一特性AOP相关知识。部分参考资料:《Spring实战(第4版)》《轻量级JavaEE企业应用实战(第四版)》Spring官方文档W3CSchoolSpring教程易百教程Spring教程一、AOP——另一... 查看详情

springaop面向切面编程-异常+最终通知(了解)(代码片段)

总结:Aspectj表示切面执行时间,用的通知(Advice)。这个通知可以使用注解表示。5个注解表示切面的5个执行时间,这些注解叫做通知注解。@Before:前置通知👉【Spring】AOP面向切面编程-前置通知&#x... 查看详情

springaop面向切面编程-前置通知(代码片段)

总结:Aspectj表示切面执行时间,用的通知(Advice)。这个通知可以使用注解表示。5个注解表示切面的5个执行时间,这些注解叫做通知注解。@Before:前置通知@AfterRetunring:后置通知@Around:环绕... 查看详情

springaop面向切面编程-环绕通知(掌握)(代码片段)

总结:Aspectj表示切面执行时间,用的通知(Advice)。这个通知可以使用注解表示。5个注解表示切面的5个执行时间,这些注解叫做通知注解。@Before:前置通知@AfterRetunring:后置通知@Around:环绕... 查看详情

一文彻底搞懂python中的装饰器偏函数(代码片段)

装饰器要讲清楚装饰器,首先要知道一些前置概念。下文涉及到这些概念的地方,会展开讲述。什么是装饰器?装饰器是一种AOP(面向切面编程)的设计模式。面向对象编程往往需要通过继承或组合依赖等方... 查看详情