Spring的AOP开发-基于xml配置的AOP

目录

基于xml配置的AOP

xml方式AOP快速入门

xml方式AOP配置详解

xml方式AOP原理剖析(后面再深入理解一下)

AOP底层两种生成Proxy的方法


基于xml配置的AOP

xml方式AOP快速入门

  • 在前面我们自己编写的AOP基础代码还存在一些问题,主要是
    • 被增强的范围写死了
    • 通知对象的方法在代码中写死了
    • 具体文章传送:Spring的AOP开发-AOP简介-CSDN博客
    •   

  •  我们可以通过配置文件解决上述问题
    • 配置增强的范围(配置目标对象)---切点表达式
    • 配置目标对象被哪些通知方法所增强,以及执行的顺序
    • 配置文件的设计,配置文件(注解)的解析工作,Spring已经帮我们封装好了。在java web中设计到一些该知识点,具体文章参照内容管理-CSDN创作中心,其中AOP相关知识点。

  • xml方式配置AOP的步骤
    • 导入AOP相关坐标
      •         <dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.19</version></dependency>
    • 准备目标类、增强类、并配置给Spring管理
      • 还是参考往期文章,我是用的是注解的方式,只需要在配置文件中,设置组件扫描的范围即可。Spring的AOP开发-AOP简介-CSDN博客
    • 配置切点表达式(哪些方法被增强)
    • 配置织入(切点被哪些通知方法增强,是前置增强还是后置增强)

运行测试类

package com.example.Test;import com.example.Service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestMyAOP {public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");UserService userService = applicationContext.getBean(UserService.class);userService.show1();}
}

 运行结果如下

xml方式AOP配置详解

  • xml配置AOP还是很简单的,具体细节如下
    • 切点表达式的配置方式
    • 切点表达式的配置语法
      • execution([访问修饰符] 返回类型 包名.类名.方法名(参数))
      • 访问修饰符可以省略不写
      • 返回值类型、某一级包名、类名、方法名可以使用表示*表示任意
      • 包名与类名之间使用单点.表示该包下的类,使用双点..表示该包及其子包下的类
      • 参数列表可以使用两个点..表示任意参数
      • 也可以参考java web专栏往期文章:AOP进阶-切入点表达式-execution-CSDN博客
    • 通知类型
      • AspectJ的通知由以下通知类型
      • 通知类型描述
        Before在目标方法执行之前执行的通知,用于进行准备工作或检查
        After在目标方法执行之后执行的通知,用于进行清理工作或资源释放,最终都会执行
        AfterReturning在目标方法正常执行并返回结果后执行的通知,用于处理返回值或记录结果,目标方法异常时,不再执行
        AfterThrowing在目标方法抛出异常后执行的通知,用于捕获和处理异常
        Around在目标方法执行前后都可以执行的通知,用于包裹目标方法的执行过程、控制和干预,目标方法异常时,环绕后方法不再执行
        StaticInitialization静态初始化代码块的通知,当类被加载时执行
        Initialization对象初始化代码块的通知,当对象被创建时执行
        FieldGet字段读取操作的通知,当访问字段时执行
        FieldSet字段赋值操作的通知,当修改字段值时执行
        MethodExecution方法执行的通知,包括Before、After、AfterReturning和AfterThrowing等通知的集合
      • 参考文章:AOP进阶-通知类型-CSDN博客,在该文章中使用的是注解方式来配置AOP。
      • 以下是通过xml方式来配置AOP前5种通知方式的代码示例
        • 5种通知方法        
          • package com.example.advice;import org.aspectj.lang.ProceedingJoinPoint;// 自定义增强类,内部提供增强方法
            public class MyAdvice {// todo 前置通知public void beforeAdvice() {System.out.println("前置通知");}// todo 后置通知public void afterAdvice() {System.out.println("后置通知");}// todo 环绕通知public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {// 前置通知System.out.println("环绕通知:前置通知");Object res = proceedingJoinPoint.proceed(); // 执行目标方法System.out.println("环绕通知中目标方法执行了");// 后置通知System.out.println("环绕通知:后置通知");return res;}// todo 异常通知public void afterThrowingAdvice() {System.out.println("异常抛出通知...出现异常才会执行");}// todo 最终通知public void endAdvice() {System.out.println("最终通知....怎么样都会通知");}}
            
        • xml配置文件

          • <?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 http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"><!-- 配置目标类 --><bean id="userService" class="com.example.Service.ServiceImpl.UserServiceImpl"/><!-- 配置通知类 --><bean id="myAdvice" class="com.example.advice.MyAdvice"/><!-- AOP配置 --><aop:config><!-- 切点表达式,指定哪些方法被增强 --><aop:pointcut id="MyPointCut"expression="execution(void com.example.Service.ServiceImpl.UserServiceImpl.*(..))"/><!-- 配置织入,指定哪些切点与哪些通知进行结合 --><aop:aspect ref="myAdvice"><!--            前置通知--><aop:before method="beforeAdvice" pointcut-ref="MyPointCut"/><!--            后置通知--><aop:after-returning method="afterAdvice" pointcut-ref="MyPointCut"/><!--            环绕通知--><aop:around method="around" pointcut-ref="MyPointCut"></aop:around><!--            异常通知--><aop:after-throwing method="afterThrowingAdvice" pointcut-ref="MyPointCut"/><!--            最终通知--><aop:after method="endAdvice" pointcut-ref="MyPointCut"/></aop:aspect></aop:config>
            </beans>
            
        • 测试代码

          • package com.example.Test;import com.example.Service.UserService;
            import org.springframework.context.ApplicationContext;
            import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestMyAOP {public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");UserService userService = applicationContext.getBean(UserService.class);userService.show1();}
            }
            
          • 运行结果如下

        • 上述的运行结果也多多少少体现了各种通知类型的通知顺序, 具体可以参照文章:AOP进阶-通知顺序-CSDN博客,同时由于目标方法没有运行错误,所以,异常通知类无法通知,造出异常后:


  • AOP的配置两种方式
    • 使用<advisor>配置切面,使用较少,创建一个类,实现不同的类型的通知接口,从而不用在配置文件设置通知类型。
      • 实现通知接口的类(增强类,指定通知类型)
        • package com.example.advice;import org.springframework.aop.AfterReturningAdvice;
          import org.springframework.aop.MethodBeforeAdvice;import java.lang.reflect.Method;public class MyAdvice2 implements MethodBeforeAdvice, AfterReturningAdvice {@Overridepublic void before(Method method, Object[] objects, Object o) throws Throwable {System.out.println("前置通知~~~~~~");}@Overridepublic void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {System.out.println("后置通知~~~~~~");}}
          
      • 配置文件(该配置文件中并没有指定通知类型)
        • <?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 http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"><!-- 配置目标类 --><bean id="userService" class="com.example.Service.ServiceImpl.UserServiceImpl"/><!-- 配置通知类 --><bean id="myAdvice2" class="com.example.advice.MyAdvice2"/><aop:config><aop:pointcut id="MyPointCut" expression="execution(* com.example.Service.ServiceImpl.UserServiceImpl.*(..))"/><aop:advisor advice-ref="myAdvice2" pointcut-ref="MyPointCut"></aop:advisor></aop:config></beans>
          
      • 测试类

        • package com.example.Test;import com.example.Service.UserService;
          import org.springframework.context.ApplicationContext;
          import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestMyAOP {public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext2.xml");UserService userService = applicationContext.getBean(UserService.class);userService.show1();}
          }
          
      • 运行结果如下

    • 使用<aspect>配置切面,上述配置中都是使用的该方法
  • Spring定义了一个Advice接口,实现该接口的类都可以作为通知类出现(一般都是实现其子类)
  • 两种配置方案的比较
    • 语法形式不同
      • advisor是通过实现接口来确认通知类型
      • aspect是通过配置确认通知类型,更加灵活
    • 可配置的切面数量不同
      • 一个advisor只能配置一个固定通知和一个切点表达式
      • 一个aspect可以配置多个通知和多个切点表达式
    • 使用场景不同 
      • 运行任意搭配情况下可以使用aspect进行配置
      • 如果通知类型单一、切面单一的情况下可以使用advisor进行配置
      • 在通知类型已经固定,不用人为指定通知类型时,可以使用advisor进行配置,例如后面会学习的Spring事务控制的配置。

xml方式AOP原理剖析(后面再深入理解一下)

  •  首先根据自定义命名空间进行解析,为标签指定解析器,该解析器向Spring容器中注入AspectJAwareAduisorAutoProxyCreator(其本质是一个beanPostProcessor,在对应的after方法中生成bean的代理对象存储到容器中)源码真的难看(记住过程)。

AOP底层两种生成Proxy的方法

  • 动态代理的实现的选择,在调用getProxy()方法时,我们可以选用的AopProxy接口有两个实现类,如上图,这两个都是动态生成代理对象的方式,一种是基于JDK的,一种是基于Cglib的
    • 代理技术使用条件配置方式
      JDK动态代理技术目标类有接口,是基于接口动态生成实现类的代理对象目标类有接口的情况下,默认方式
      Cglib动态代理技术目标类无接口且不能用final修饰,是基于被代理对象动态生成子对象为代理对象

      目标了无接口时,默认使用该方式;目标类有接口时,手动配置<aop:config proxy-target-class="true">强制使用Cglib方式

       
    • 代理对象实质上是接口实现类的对象。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/130257.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【java学习】对象的产生(18)

文章目录 1. 初始化赋值2. 匿名对象3. 练习3.1. 习题一3.2. 习题二 4. 总结 1. 初始化赋值 当一个对象被创建时&#xff0c;会对其中各种类型的成员变量自动进行初始化赋值。除了基本数据类型之外的变量类型都是引用类型&#xff0c;如上节的 Person 和前面讲过的数组。 成员…

linux | linux扩大磁盘空间 | centos7.9 | 虚拟机

注意&#xff1a;可以完全参考下面这边博客&#xff08;我只是搬运工&#xff09; centos扩大磁盘空间 简单讲讲&#xff0c;为什么有点失落落的&#xff1f; 明明就是一个 很程序化的东西 可是网上一大推 天花乱坠 而且很多人都是半吊子水&#xff0c;甚至半吊子都没有 通过关…

如何打造一个网络框架模块对接服务器

一、了解网络框架的基本原理 在开始打造网络框架模块之前&#xff0c;首先需要了解网络框架的基本原理。网络框架是一个软件模块&#xff0c;用于处理网络通信的各种细节&#xff0c;包括数据传输、协议解析、错误处理等。常见的网络框架有HTTP、TCP/IP、WebSocket等。 对啦&…

mysql面试题32:MySQL数据库服务器性能分析的方法命令有哪些?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:MySQL数据库服务器性能分析的方法命令有哪些? MySQL数据库服务器性能分析的方法和命令有以下几种: EXPLAIN命令:用于分析查询语句的执行计划,…

嵌入式C语言中整形溢出问题分析

整型溢出有点老生常谈了&#xff0c;bla, bla, bla… 但似乎没有引起多少人的重视。整型溢出会有可能导致缓冲区溢出&#xff0c;缓冲区溢出会导致各种黑客攻击。 今天分享一篇文章&#xff0c;希望大家都了解一下整型溢出&#xff0c;编译器的行为&#xff0c;以及如何防范&a…

Redis-分布式锁

分布式锁相关内容 超卖问题切入可以使用互斥锁给先获取到锁的线程加锁吗&#xff1f;使用redis分布式锁解决超卖问题setnx命令实现分布式锁为什么需要设置过期时间&#xff1f;Redis实现分布式锁如何合理控制锁的有效时长 redisson实现分布式锁 超卖问题切入 我们先来看一个项目…

【附代码】使用Shapely计算多边形外扩与收缩

文章目录 相关文献效果图代码 作者&#xff1a;小猪快跑 基础数学&计算数学&#xff0c;从事优化领域5年&#xff0c;主要研究方向&#xff1a;MIP求解器、整数规划、随机规划、智能优化算法 本文档介绍如何使用 Shapely Python 包 计算多边形外扩与收缩。 如有错误&…

Git分支教程:详解分支创建、合并、删除等操作

GIT分支是Git中用于开发和管理代码的重要概念之一。每个分支都是一个独立的代码版本&#xff0c;可以在分支上进行修改和提交&#xff0c;而不影响主线&#xff08;通常是master分支&#xff09;上的开发工作。 分支的作用&#xff1a; 并行开发&#xff1a;多个开发人员可以…

k8s containerd查看镜像

直接查看crictl image会报错&#xff1a; 1) crictl config runtime-endpoint unix:///run/containerd/containerd.sock 2) vi /etc/crictl.yaml 3) systemctl daemon-reload 此时&#xff0c;再查看image:

【计算机网络】UDP协议编写群聊天室----附代码

UDP构建服务器 x 预备知识 认识UDP协议 此处我们也是对UDP(User Datagram Protocol 用户数据报协议)有一个直观的认识; 后面再详细讨论. 传输层协议无连接不可靠传输面向数据报 网络字节序 我们已经知道,内存中的多字节数据相对于内存地址有大端和小端之分, 磁盘文件中的…

Git相关知识(1)

目录 1.初识Git 1.基础知识 2.centos中下载 2.基本操作 1.创建本地仓库 2.配置本地仓库 3.版本库、工作区、暂存区 4.添加文件 5.add和commit对git文件的作用 6.修改文件 7.版本回退 8.撤销修改 9.删除文件 3.分支操作 1.HEAD与分支 2.创建分支 3.删除分支 …

sface人脸相似度检测

sface人脸相似度检测&#xff0c;基于OPENCV&#xff0c;人脸检测采用yunet&#xff0c;人脸识别采用sface&#xff0c;支持PYTHON/C开发&#xff0c;图片来自网络&#xff0c;侵权请联系本人立即删除 yunet人脸检测sface人脸识别&#xff0c;检测两张图片的人脸相似度