Spring切面之一
为什么要使用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>
Spring切面之一的更多相关文章
- spring切面-单线程简单权限判定
spring切面简单模拟用户权限判定 需求: 游客:仅注册用户 用户:修改,注册 管理员:删除,查询,修改,注册 1,文件配置 导包 src下创建applicationContext.xml文件配置如 ...
- Spring 切面可以应用五种类型的通知?
Spring 切面可以应用五种类型的通知: before:前置通知,在一个方法执行前被调用. after: 在方法执行之后调用的通知,无论方法执行是否成功. after-returning: 仅当方法 ...
- spring切面编程AOP 范例一
参照网上的spring AOP编程实例进行配置,但是碰到了几个坑.这篇文章重点讲解一下我踩过的两个坑: 1.使用@Service自动装配的时候,基础扫描包配置要正确: 2.xml中切面配置中的exec ...
- Spring切面通知执行的顺序(Advice Order)
问题描述 如果在Spring的程序中同时定义了环绕通知(Around)和前置通知(Before)..那么,有以下问题: 1.怎么让两个切面通知都起作用 2.或者让两者切面按自己指定的顺序进行执行? 3 ...
- Spring切面编程步骤
什么是面向切面编程 面向对象的编程主要注重核心业务,而面向切面编程主要关注一些不是核心的业务,但又是必须的辅助功能,比如一个完整的系统中,记录平时系统运行时抛出的异常,需要我们去记录,以便我们对系统尽 ...
- 扩展Spring切面功能
概述 Spring的切面(Spring动态代理)在Spring中应用十分广泛,例如还有事务管理,重试等等.网上介绍SpringAop源码很多,这里假设你对SpringAop有基本的了解.如果你认为Sp ...
- Spring切面编程实践【原创】
定义 什么叫Spring面向切面编程(AOP),请自行百度,这边就不做详细介绍了. 场景 有两个对象,字典和工程信息Bean,每次新增或修改对象时,记录新增和修改的时间. 基类定义 package m ...
- 扩展Spring切面
概述 Spring的切面(Spring动态代理)在Spring中应用十分广泛,例如还有事务管理,重试等等.网上介绍SpringAop源码很多,这里假设你对SpringAop有基本的了解.如果你认为Sp ...
- spring切面拦截实现
1.建立业务类(英雄战斗实现类) package com.g2.api; public interface Weapon { int attack(); String getName(); } pac ...
- 《Java Spring框架》Spring切面(AOP)配置详解
1. Spring 基本概念 AOP(Aspect Oriented Programming)称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等待,Struts2 ...
随机推荐
- Java 注解 初探 (一)
自JDK1.5之后,就开始出现注解.想要了解注解的来源和注解的用法,通过搜索引擎大都是针对某一个注解的解释,很难找到关于注解系列的文章,便自己看下. 基于Annotation的注释,说明Annotai ...
- 书写可维护的javascript
内容介绍 编写可维护的代码很重要,因为大部分开发人员都花费大量时间维护他人代码. 1.什么是可维护的代码? 一般来说可维护的代码都有以下一些特征: 可理解性---------其他人可以接手代码并理解它 ...
- HTTP结构讲解——《HTTP权威指南》系列
HTTP结构 第二部分的5章主要介绍了HTTP服务器,代理,缓存,网关和机器人应用程序,这些都是Web系统架构的构造模块. Web服务器 第五章 Web服务器会对HTTP请求进行处理并提供响应.术语& ...
- qs.js - 更好的处理url参数
第一次接触 qs 这个库,是在使用axios时,用于给post方法编码,在使用过程中,接触到了一些不同的用法,写在这里分享一下. qs.parse qs.parse 方法可以把一段格式化的字符串转换为 ...
- 技本功丨利用 Atomic 构建 React 项目工作流,so easy!
近日刷微博,#2018年结婚率创新低#荣登热门话题NO.1,沪浙最不积极. 生活压力越大,缺爱的人也越来越多...据本萌的不完全观察,程序猿虽然是压力加成的职业,在袋鼠云还是有不少早早脱了单.至于,脱 ...
- Activity 在横竖屏切换情况下的生命周期变化
title: Activity 在横竖屏切换情况下的生命周期变化 date: 2018-04-26 23:05:57 tags: [Activity] categories: [Mobile,Andr ...
- 根据Unicode码生成汉字
最近需要一批汉字字符数据,类似数字字符与ASCII码之间的对应关系,汉字字符与Unicode码之间也存在对应关系. 所以可以遍历Unicode码批量生成汉字. 其中,汉字为宽字符,输出时候注意需要修改 ...
- C++的反思与总结
博客作业学到的东西: 1.博客作业应该说是从寒假就开始了,因为博客作业,所以我寒假时都不敢玩得太疯狂,毕竟还有博客作业没做呢.有了博客作业,我就从一个连博客是什么都不知道无知少年,开始去了解博客是什么 ...
- 静默调用ShellContextMenu 实现QQ文件共享
我在CSDN提问题一直没人回复,一下午时间自己终于解决了问题 http://bbs.csdn.net/topics/391916381 现将过程录下 先说需求,我想实现的功能是 在程序中对文件调用百度 ...
- Java 将数字转为16进制,然后转为字符串类型 将空格去掉。终结版
//十进制转为十六进制 public class ArrayTest7 { public static void main(String[] args){ System.out.println(toH ...