Spring切面之一
2024-08-26 18:56:40
为什么要使用AOP,在编写程序的时候,除了不必关心依赖的组件如何实现,在实际开发过程中,还需要将程序中涉及的公共问题集中解决。AOP是Aspect-Oriented Programming的简称,意思是面向切面编程。是对OOP的补充和完善,比如在开发中,所有的业务方法都需要日志记录、参数验证、事务处理,这些公共的处理如果放在每个业务方法中,系统会变的十分臃肿,即使写成公用类进行调用,也很难维护。散步在系统各处的需要在实现业务系统时关注的事情被称为“切面”,也称之为关注点,AOP的思想就是把这些公用部分从业务方法中提取出来,集中处理。
AOP将软件系统分为两个部分:核心关注点和横切关注点。术语:
1切面:Aspect:切面是系统中抽象出来的某一个模块。
2.连接点:JoinPoint:程序执行过程中某个特定的点,如调用某方法或处理异常时,在SpringAOP中,连接点总是代表着某个方法的执行。
3.通知:Advice:通知是切面具体实现,是放置”切面代码的“类。
4.切入点:PointCut:多个连接点组成一个切入点,可以使用切入点表达式表示。
5.目标对象:Target Object:包含一个连接点的对象,即被拦截的对象。
6.AOP代理:AOP Proxy:AOP框架产生的对象,是通知和目标对象的结合体。
7.织入:Weaving:将切入点和通知结合的过程称之为织入。
package com.sp.IC; import com.sp.bean.OutOfStockException; //手机业务接口 public interface PhoneBiz { public void buyPhone(int num);//购买手机; public void salePhone(int num) throws OutOfStockException;//销售手机 }
package com.sp.bean; import com.sp.IC.PhoneBiz; public class PhoneBizImpl implements PhoneBiz{ //库存属性; int num=140; public void buyPhone(int num) { System.out.println("手机进货"+num+"部"); } public void salePhone(int num) throws OutOfStockException{ if(this.num<num){ throw new OutOfStockException("库存不足,客户需要"+num+"部手机,库存只有"+this.num+"部"); } System.out.println("手机销售"+num+"部"); } }
package com.sp.bean; public class OutOfStockException extends Exception { //缺货异常; public OutOfStockException(String msg){ super(msg); } }
package com.sp.bean; import java.text.SimpleDateFormat; import java.util.Date; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; //通知类; public class LogAspect { //前置通知; public void before(JoinPoint jp)throws Throwable{ Object[]args=jp.getArgs(); //目标方法所有参数; String methodName=jp.getSignature().getName(); //获得目标方法名称; if("buyPhone".equals(methodName)){ System.out.println(currentTime()+"即将进行进货操作,数量为:"+args[0]); } if("salePhone".equals(methodName)){ System.out.println(currentTime()+"即将进行销售操作,数量为:"+args[0]); } } //***********************后置通知*********************** public void afterReturning(JoinPoint jp)throws Throwable{ String methodName=jp.getSignature().getName();//获得签名方法的名字; if("buyPhone".equals(methodName)){ System.out.println(currentTime()+"进货操作完毕"); } if("salePhone".equals(methodName)){ System.out.println(currentTime()+"销售操作完毕"); } } public void after(JoinPoint jp)throws Throwable{ String methodName=jp.getSignature().getName(); if("buyPhone".equals(methodName)){ System.out.println(currentTime()+"进货操作完毕,异常也要执行完毕的最终通知..."); } if("salePhone".equals(methodName)){ System.out.println(currentTime()+"销售操作完毕,异常也要执行完毕的最终通知..."); } } //环绕通知; public Object aroundTest(ProceedingJoinPoint pjp)throws Throwable{ String method=pjp.getSignature().getName(); long begin=System.currentTimeMillis();//当前时间; System.out.println(currentTime()+":"+method+"方法开始执行,计时开始!"); try { return pjp.proceed(); }finally{ long end=System.currentTimeMillis(); System.out.println(currentTime()+":"+method+"方法执行完毕,耗时:"+(end-begin)+"毫秒"); } } //***********************后置通知结束********************* public void afterThrowing(JoinPoint jp,OutOfStockException e){ String methodName=jp.getSignature().getName(); System.out.println(currentTime()+methodName+"方法执行,发生缺货异常"+e.getMessage()); } //输出时间的方法; public String currentTime(){ SimpleDateFormat sdf=new SimpleDateFormat("yyyy:MM:dd HH:mm:ss"); return sdf.format(new Date()); } }
<?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:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <!-- 目标业务对象 --> <bean id="phoneBiz" class="com.sp.bean.PhoneBizImpl"></bean> <!-- 日志管理切面类 --> <bean id="logAspectBean" class="com.sp.bean.LogAspect"></bean> <!-- Aop配置 --> <aop:config> <aop:pointcut expression="execution(void *Phone(int))" id="p1"/> <!-- 配置日志管理切面 --> <aop:aspect id="logAspect" ref="logAspectBean"> <!-- 配置日志记录前置通知 --> <aop:before method="before" pointcut-ref="p1"/> <!-- 配置日志记录后置通知 --> <aop:after method="afterReturning" pointcut-ref="p1"/> <!-- 配置日志记录异常通知; --> <aop:after-throwing method="afterThrowing" pointcut-ref="p1" throwing="e"/> <!-- 配置日志记录最终通知 --> <aop:after method="after" pointcut-ref="p1"/> <!-- 配置日志记录环绕通知 --> <aop:around method="aroundTest" pointcut-ref="p1"/> </aop:aspect> </aop:config> </beans>
最新文章
- PG 函数的易变性(Function Volatility Categories)
- 大批量GPS坐标转百度坐标
- arc下内存泄漏的解决小技巧
- jdbc链接mysql转
- C++ 提取字符串中的数字
- Smart210学习记录------paltform总线
- linxu c语言 fcntl函数和flock函数区别 【转】
- LFI漏洞利用总结(转载)
- linux编程之指针
- osg 基本几何图元
- 关于AJAX+HTML5+ASHX进行全静态页面的数据交互
- ASP.NET CORE 1.0 初次接触
- TCP/IP 标志位 SYN ACK RST UTG PSH FIN
- Vim中常用的命令行
- python3全栈开发-并发编程,多进程的基本操作
- JSON数组形式字符串转换为List<;Map<;String,String>;>;的几种方法
- 洛谷P1955 程序自动分析 [NOI2015] 并查集
- Asp.net core 学习笔记 ( Web Api )
- (待解决,效率低下)47. Permutations II C++回溯法
- Pullword 分词工具
热门文章
- MySQL☞左外链接与右外连接
- Kubernetes-----Endpoints
- Python-2.7 配置tab自动补全功能
- 原生开发小程序 和 wepy 、 mpvue 对比
- 【转载】windows安装python2.7后的注册表问题
- 关于XML文档操作类
- 01慕课网《vue.js2.5入门》——基础知识
- PHP 函数总结
- 如何解决Unsupported Architecture. Your executable contains unsupported architecture &#39;[x86_64, i386]
- 复利计算1.0,2.0,3.0(java)