当前位置: 首页 > news >正文

基于XML的AOP开发

AOP 为 Aspect Oriented Programming 的缩写,意思为面向切面编程

AOP相关术语:

目标对象(Target):

你要去代理的对象,可以理解为之前很单纯的那个对象。

代理对象(Proxy):

你把你那个单纯的对象给我,我给你一个更强的对象

连接点(Joinpoint):

所谓的连接点就是指哪些可以被拦截到的方法。

切入点(Pointcut):

对连接点再去具体一点,真正要拦截的方法

通知/增强(Advice):

你把方法拦截了,你要干嘛?要去做一些增强(通知),前置通知、后置通知、异常通知、最终通知、环绕通知。

切面(Aspect):

切入点和通知的结合

总结以上术语的图:

AOP开发明确事项:

1. 编写核心业务代码(目标类的目标方法)切入点。
2. 把公用代码抽取出来,制作成通知(增强功能方法)通知。
3. 在配置文件中,声明切入点与通知间的关系,即切面。

导入AOP相关坐标:

<!-- aspectj的织入(切点表达式需要用到该jar包) -->
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.13</version>
</dependency>

创建目标接口和目标实现类:

public interface AccountService {/* 目标方法: 切入点 要进行拦截的方法 */public void transfer();
}
public class AccountServiceImpl implements AccountService {/*要切入的方法*/@Overridepublic void transfer() {System.out.println("this is transfer method");}
}

创建通知类:

 这个类里面写的就是具体怎么去增强对象

public class MyAdvice {/*** 前置通知*/public void before() {System.out.println("before advice");}/*** 后置通知*/public void after() {System.out.println("after advice");}}

将目标类和通知类对象创建权交给spring:

    <!--目标类交给IOC容器--><bean id="accountService" class="com.findyou.service.Impl.AccountServiceImpl"></bean><!--通知类交给IOC容器--><bean id="myAdvice" class="com.findyou.advice.Myadvice"></bean>

 xml里面的aop配置:

xml里面的aop配置,用的是<aop:config>。

里面写你写好的通知类,也就是你要用哪个类去增强我的对象,用ref去引入,前提是你已经把这个类放到ioc容器里面了。用的标签是<aop:aspect ret = "">。

 在这个基础上再进行续写,这个通知类里面有很多的方法啊,你要说出来,哪一个是前置通知,哪一个是后置通知等等。前置通知也即是执行原方法之前要做的事情。前置通知的标签是<aop:before>, 里面的参数有 method = "类里面的哪个方法", pointcut = "你要限制谁,增强谁",可以理解为:当我触发pointcut里面的方法的时候之前就回去执行 method里面的方法。

 无论是 前置通知和后置通知,里面都要有个属性:pointcut, point里面写的就是下面要讲的 切点表达式。如果这个要经常去写的话,可以把pointcut给提取出来。用的时候把之前的pointcut属性改为 pointcut-ref  =  "提取出来的pointcutId";

<aop:pointcut id="myPointcut" expression="execution(* com.findyou.service.Impl.AccountServiceImpl.*(..))" />

切点表达式:

execution([修饰符] 返回值类型 包名.类名.方法名(参数))

  •  访问修饰符可以省略
  • 返回值类型、包名、类名、方法名可以使用星号 * 代替,代表任意
  • 包名与类名之间一个点 . 代表当前包下的类,两个点 .. 表示当前包及其子包下的类
  • 参数列表可以使用两个点 .. 表示任意个数,任意类型的参数列表。

当然最常用的也还是: * com.findyou.service.Impl.AccountServiceImpl.*  这样的格式。 

总的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:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!--目标类交给IOC容器--><bean id="accountService" class="com.findyou.service.Impl.AccountServiceImpl"></bean><!--通知类交给IOC容器--><bean id="myAdvice" class="com.findyou.advice.Myadvice"></bean><!-- AOP配置 --><aop:config><!--execution 翻译为 执行--><!-- 定义切点与通知 --><aop:aspect ref="myAdvice"><!-- 切点表达式,指定在哪些方法执行前后添加通知 --><aop:pointcut id="myPointcut" expression="execution(* com.findyou.service.Impl.AccountServiceImpl.*(..))" /><!-- 将通知应用于切点 配置的是前置通知 --><aop:before method="before" pointcut = "execution(public void com.findyou.service.Impl.AccountServiceImpl.transfer())"/><aop:after-returning method="after" pointcut-ref="myPointcut"/></aop:aspect></aop:config></beans>

测试代码:

package com.findyou;import com.findyou.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;/*** @Title: MyTest* @Author FindYou* @Package com.findyou* @Date 2024/12/5 上午11:17* @description: 测试类*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class MyTest {@Autowiredprivate AccountService accountService;@Testpublic void testTransfer() throws Exception {accountService.transfer(); // 先去执行的是前置通知}}

运行的结果是:
 

http://www.lryc.cn/news/497948.html

相关文章:

  • pdf也算是矢量图——pdf大小调整--福昕pdf
  • Web应用程序文件包含-Server2233-解析
  • AI开发: 知识图谱的初识,学会制作知识图谱- Python 机器学习
  • Ubuntu Linux用户与组的管理
  • 算力100问☞第32问:密集计算的关键技术有哪些?
  • Rust : 生成日历管理markdown文件的小工具
  • 【并集查询】.NET开源 ORM 框架 SqlSugar 系列
  • 基于单片机的智能农田灌溉节水系统设计及应用
  • jmeter如何导出中文版的测试报告?
  • AIGC 与艺术创作:变革与机遇
  • 【Axios】如何在Vue中使用Axios请求拦截器
  • element Plus中 el-table表头宽度自适应,不换行
  • 【Android】从事件分发开始:原理解析如何解决滑动冲突
  • 如何使用JDBC向数据库中插入日期数据???
  • 高频面试题(含笔试高频算法整理)基本总结回顾29
  • Flink日志配置
  • 论文 | EfficientRAG: Efficient Retriever for Multi-Hop Question Answering
  • 超越Hallo和AniPortrait?音频驱动肖像动画新方法LetsTalk
  • 手机LCD分区刷新技术介绍
  • WPF软件花屏的解决方法
  • 深度学习笔记——模型压缩和优化技术(蒸馏、剪枝、量化)
  • 开发手札:Win+Mac下工程多开联调
  • 项目基于oshi库快速搭建一个cpu监控面板
  • 【c语言】指针3
  • 【开源】A063—基于Spring Boot的农产品直卖平台的设计与实现
  • Can‘t find variable: token(token is not defined)
  • 【JavaEE 初阶】⽹络编程套接字
  • 【Linux内核】Hello word程序
  • PHP 与 MySQL 搭配的优势
  • 深入浅出:PHP中的变量与常量全解析