Spring AOP的概念与实现过程详解

2023-05-16 0 2,751

目录

Aop

什么是Aop?

AOP就是面向切面编程,通过预编译方式以及运行期间的动态代理技术来实现程序的统一维护功能

什么是切面,我理解的切面就是两个方法之间,两个对象之间,两个模块之间就是一个切面。假设在两个模块之间需要共同执行一系列操作,并且最后将这一系列操作注入到两个模块之间的指定位置。此时这一系列操作就是切面,注入这些操作的位置称之为切点。

举例:公司员工上班

A员工上班需要在前台进行打卡,同样的B员工…其他员工都需要在前台打卡,那么如果为每一位员工提供单独的打卡通道就有些过于浪费资源。像这样

Spring AOP的概念与实现过程详解

于是,在前台这个位置设置接口,声明公共的打卡方法,所有员工共同通过该接口进行打卡,那么在打卡时的一系列校验或者记录的整个操作就可以被称之为切面,前台这个空间位置就被称之为切点,如下图所示

Spring AOP的概念与实现过程详解

aop主要作用就是进行日志记录、事务/异常处理等功能以便更好地维护开发,主要目的就是将这些行为从项目的业务逻辑代码中分离出来并且降低各个业务逻辑模块之间的耦合度。保证在执行aop操作的同时不会影响到项目的业务逻辑代码

几个概念

Aspect:切面 Aspect中会包含一些pointCut切入点以及一些Advice

Advice:通知 切面需要完成的工作,通过before、after、around来区别是在连接点之前或者之后 或者环绕

Target:目标 目标对象,该对象会被织入advice

PointCut:切点 即切面通知执行的地点 advice将会在这里发生

JointPoint:连接点 所有方法的执行点

PointCut用来修饰JointPoint,PointCut是advice执行的点,而JointPoint表示所有方法的执行点,通过PointCut可以确定哪些JointPoint是可以被织入的点

我们通常不希望advice会在所有的JointPoint点执行,PointCut的作用就是可以进行校验来更精准的匹配执行点。简单概括就是Jointpoint可以执行但未必执行,只有PointCut匹配到了JointPoint才可以在该点执行

Aspect切面可以理解为PointCut+Advice

使用AOP织入导入包

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.9.7</version>
  <scope>runtime</scope>
</dependency>

实现aop方式一

使用spring内置的API接口

准备:UserService、UserServiceImpl简单实现CRUD

在spring核心配置文件applicationContext.xml中配置aop:

<?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: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                  https://www.springframework.org/schema/aop/spring-aop.xsd\">
  <bean id=\"userServiceImpl\" class=\"com.mount.service.UserServiceImpl\"/>
  <bean id=\"log\" class=\"com.mount.log.log\"/>
  <bean id=\"afterLog\" class=\"com.mount.log.AfterLog\"/>
  <!--  配置AOP  -->
  <aop:config>
    <!-- 切入点 expression表达式  表示从哪里开始执行   -->
    <aop:pointcut id=\"pointcut\" expression=\"execution(* com.mount.service.UserServiceImpl.*(..))\"/>
    <!--      执行环绕增强  -->
    <aop:advisor advice-ref=\"log\" pointcut-ref=\"pointcut\"/>
    <aop:advisor advice-ref=\"afterLog\" pointcut-ref=\"pointcut\"/>
  </aop:config>
</beans>

编写执行前后日志

// 执行前  实现spring内置接口MethodBeforeAdvice
public class log implements MethodBeforeAdvice {
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println(target.getClass().getName()+\"执行了\"+method.getName()+\"方法\");
    }
}
// 执行后 实现AfterReturningAdvice 
public class AfterLog implements AfterReturningAdvice {
  public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
    System.out.println(target.getClass().getName()+\"调用了\"+method.getName()+\"方法\"+\"返回的结果为\"+returnValue);
  }
}

测试:

@Test
public void test01(){
  ApplicationContext context = new ClassPathXmlApplicationContext(\"applicationContext.xml\");
  UserService bean = context.getBean(\"userServiceImpl\", UserService.class);
  bean.insert();
}

实现aop方式二

使用自定义类,只需要在applicationContext.xml中重新配置aop,并且自己diy一个类即可,在配置时可以选择任一方法为前置日志或后置日志即可

<!--  配置AOP 方式二  -->
<bean id=\"diy\" class=\"com.mount.diyLog.diyLogImpl\"/>
<aop:config>
  <!--     自定义切面 ref引入的类   -->
  <aop:aspect ref=\"diy\">
    <aop:pointcut id=\"pointcut\" expression=\"execution(* com.mount.service.UserServiceImpl.*(..))\"/>
    <aop:before method=\"before\" pointcut-ref=\"pointcut\"/>
    <aop:after method=\"after\" pointcut-ref=\"pointcut\"/>
  </aop:aspect>
</aop:config>

diylog类

public class diyLog {
  public void before(){
    System.out.println(\"===before方法执行===\");
  }
  public void after(){
    System.out.println(\"===after方法执行===\");
  }
}

注解实现aop

首先需要在applicationContext.xml文件中打开SpringAOP对注解的支持

<!-- SpringAop开启注解支持 -->
<aop:aspectj-autoproxy/>
<!-- 映射自定义注解实现log类 -->
<bean id=\"annoLog\" class=\"com.mount.annoLog.annoLogImpl\"/>

annoLog

// Aspect标注该类是一个切面
@Aspect
public class annoLogImpl {
  // 前置增强
  @Before(\"execution(* com.mount.service.UserServiceImpl.*(..))\")
  public void before(){
    System.out.println(\"---方法执行前---\");
  }
  // 后置增强
  @After(\"execution(* com.mount.service.UserServiceImpl.*(..))\")
  public void after(){
    System.out.println(\"---方法执行后---\");
  }
  // 环绕增强
  @Around(\"execution(* com.yuqu.dao.UserMapperImpl.*(..))\")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println(\"环绕前\");
        Object proceed = pjp.proceed();
        System.out.println(\"环绕后\");
        System.out.println(\"执行信息:\"+pjp.getSignature());
        return proceed;
    }
}

最终打印:

环绕前
---方法执行前---
删除成功!
---方法执行后---
方法签名Integer com.mount.service.UserService.delete()
方法执行返回=1
环绕后

注意around环绕增强,如果我们执行的sql中是有返回值的话,那么必须显式的将pjp.proceed();返回回去,否则在调用处将会无法获取到结果集,报空指针异常

可以发现,around环绕增强首先执行,在执行到joinPoint.proceed()时,会执行对应方法,执行对应方法的时候才会执行前置或后置的其他增强操作

资源下载此资源下载价格为1小猪币,终身VIP免费,请先
由于本站资源来源于互联网,以研究交流为目的,所有仅供大家参考、学习,不存在任何商业目的与商业用途,如资源存在BUG以及其他任何问题,请自行解决,本站不提供技术服务! 由于资源为虚拟可复制性,下载后不予退积分和退款,谢谢您的支持!如遇到失效或错误的下载链接请联系客服QQ:442469558

:本文采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可, 转载请附上原文出处链接。
1、本站提供的源码不保证资源的完整性以及安全性,不附带任何技术服务!
2、本站提供的模板、软件工具等其他资源,均不包含技术服务,请大家谅解!
3、本站提供的资源仅供下载者参考学习,请勿用于任何商业用途,请24小时内删除!
4、如需商用,请购买正版,由于未及时购买正版发生的侵权行为,与本站无关。
5、本站部分资源存放于百度网盘或其他网盘中,请提前注册好百度网盘账号,下载安装百度网盘客户端或其他网盘客户端进行下载;
6、本站部分资源文件是经压缩后的,请下载后安装解压软件,推荐使用WinRAR和7-Zip解压软件。
7、如果本站提供的资源侵犯到了您的权益,请邮件联系: 442469558@qq.com 进行处理!

猪小侠源码-最新源码下载平台 Java教程 Spring AOP的概念与实现过程详解 http://www.20zxx.cn/704845/xuexijiaocheng/javajc.html

猪小侠源码,优质资源分享网

常见问题
  • 本站所有资源版权均属于原作者所有,均只能用于参考学习,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担
查看详情
  • 最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,建议提前注册好百度网盘账号,使用百度网盘客户端下载
查看详情

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务