Spring AOP技术(基于AspectJ)的Annotation开发
Spring AOP技术(基于AspectJ)的Annotation开发
@(Spring)[aop, spring, xml, Spring, annotation, aspectJ]
- Spring AOP技术基于AspectJ的Annotation开发
- Spring AOP的Annotation的开发
- Spring的基于AspectJ的AOP的Annotation开发
- 第一步引入jar包
- 第二步创建配置文件
- 第三步创建需增强包和类
- 第四步将类交给Spring管理
- 第五步编写测试
- 第六步编写切面类和通知
- 第七步 配置切面类
- 第八步开启AOP的自动代理
- 第九步通过注解实现AOP
- 第九步执行测试
- 通知类型
- 前置通知
- 配置切面和通知
- 单元测试
- 后置通知
- 配置切面和通知
- 单元测试
- 环绕通知
- 配置切面和通知
- 单元测试
- 异常抛出通知
- 配置切面和通知
- 单元测试
- 最终通知
- 配置切面和通知
- 单元测试
- 前置通知
- 切入点的注解
- Spring AOP小项目
- Spring的基于AspectJ的AOP的Annotation开发
- Spring AOP的Annotation的开发
Spring AOP的Annotation的开发
Spring的基于AspectJ的AOP的Annotation开发
第一步引入jar包
第二步创建配置文件
- 引入AOP的约束
<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"> </beans>
第三步创建需增强包和类
- 创建接口
package com.pc.aop.dao;/*** 客户持久层接口* * @author Switch* @data 2016年11月23日* @version V1.0*/
public interface CustomerDao {/*** 保存用户*/public void save();
}
- 创建实现类
package com.pc.aop.dao.impl;import com.pc.aop.dao.CustomerDao;/*** 用户持久层实现类* * @author Switch* @data 2016年11月23日* @version V1.0*/
public class CustomerDaoImpl implements CustomerDao {@Overridepublic void save() {System.out.println("保存用户了。。。");}
}
第四步将类交给Spring管理
<bean id="customerDao" class="com.pc.aop.dao.impl.CustomerDaoImpl" />
第五步编写测试
package com.pc.test;import javax.annotation.Resource;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import com.pc.aop.dao.CustomerDao;/*** 面向切面编程测试类* * @author Switch* @data 2016年11月23日* @version V1.0*/
// 配置Spring单元测试环境
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringAOPTest {// 注入依赖@Resource(name = "customerDao")private CustomerDao customerDao;// 测试Spring单元测试集成@Testpublic void testSpring() {customerDao.save();}
}
输出
保存用户了。。。
PS:这时候没用使用AOP进行任何增强
第六步编写切面类和通知
package com.pc.aop.advice;
import org.aspectj.lang.ProceedingJoinPoint;
/*** 切面类* * @author Switch* @data 2016年11月23日* @version V1.0*/
public class MyAspect {// 通知:校验权限public void check() {System.out.println("校验权限。。。。。。");}
}
第七步 配置切面类
<!-- 配置切面类 -->
<bean id="myAspect" class="com.pc.aop.advice.MyAspect"/>
第八步开启AOP的自动代理
<!-- 开启AOP注解自动代理 -->
<aop:aspectj-autoproxy/>
第九步通过注解实现AOP
// 配置了自动AOP代理的,需要在类上配置该注解,不然无法被识别为切面
@Aspect
public class MyAspect {// 前置通知@Before("execution(* com.pc.aop.dao.impl.CustomerDaoImpl.save(..))")// 通知:校验权限public void check() {System.out.println("校验权限。。。。。。");}
}
第九步执行测试
package com.pc.test;import javax.annotation.Resource;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import com.pc.aop.dao.CustomerDao;/*** 面向切面编程测试类* * @author Switch* @data 2016年11月23日* @version V1.0*/
// 配置Spring单元测试环境
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringAOPTest {// 注入依赖@Resource(name = "customerDao")private CustomerDao customerDao;// 测试Spring单元测试集成@Testpublic void testSpring() {customerDao.save();}
}
输出
校验权限。。。。。。
保存用户了。。。
通知类型
PS:因为在XML中已经给出了各个通知的完整测试代码,所以这里只给出通知代码和测试代码及其结果,如果想查看其他代码,请查找《Spring AOP技术(基于AspectJ)的XML开发》
前置通知
前置通知:在目标方法执行之前完成的增强。获得切入点信息。
注解:@Before
PS:接入点信息,其他类型的增强也可以通过这种方法使用。
配置切面和通知
// 配置了自动AOP代理的,需要在类上配置该注解,不然无法被识别为切面
@Aspect
public class MyAspect {// 前置通知@Before("execution(* com.pc.aop.dao.impl.CustomerDaoImpl.save(..))")// 通知:校验权限public void check(JoinPoint joinPoint) {System.out.println("校验权限。。。。。。");// 输出接入点信息System.out.println(joinPoint.toString());}
}
单元测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringAOPTest {// 注入依赖@Resource(name = "customerDao")private CustomerDao customerDao;// 测试前置通知@Testpublic void testBefore() {customerDao.save();}
}
输出
校验权限。。。。。。
execution(void com.pc.aop.dao.CustomerDao.save())
保存用户了。。。
后置通知
后置通知:在目标方法执行之后完成的增强。获得方法的返回值。
注解:@AfterReturning
配置切面和通知
// 配置了自动AOP代理的,需要在类上配置该注解,不然无法被识别为切面
@Aspect
public class MyAspect {// 后置通知@AfterReturning(value = "execution(* com.pc.aop.dao.impl.CustomerDaoImpl.delete(..))", returning = "retVal")// 通知:打印日志public void printLog(String retVal) {System.out.println("打印日志。。。。。");System.out.println("返回值为:" + retVal);}
}
单元测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringAOPTest {// 注入依赖@Resource(name = "customerDao")private CustomerDao customerDao;// 测试后置通知@Testpublic void testAfterRunning() {String delete = customerDao.delete();System.out.println(delete);}
}
输出
删除用户了。。。
打印日志。。。。。
返回值为:delete
delete
环绕通知
环绕通知:在目标方法执行前和执行后完成的增强。阻止目标方法的执行,获得方法参数。
注解:@Around
配置切面和通知
// 配置了自动AOP代理的,需要在类上配置该注解,不然无法被识别为切面
@Aspect
public class MyAspect {// 环绕通知@Around("execution(* com.pc.aop.dao.impl.CustomerDaoImpl.update(..))")// 通知:计算方法耗时public void calTime(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("方法执行前。。。。。。");// 打印参数System.out.println("参数为:" + joinPoint.getArgs()[0]);// 执行目标方法joinPoint.proceed();System.out.println("方法执行后。。。。。。");}
}
单元测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringAOPTest {// 注入依赖@Resource(name = "customerDao")private CustomerDao customerDao;// 测试环绕通知@Testpublic void testAround() {customerDao.update(6166);}
}
输出
方法执行前。。。。。。
参数为:6166
更新用户了。。。
方法执行后。。。。。。
异常抛出通知
异常抛出通知:在目标方法执行出现异常的时候完成的增强。获得异常的信息。
注解:@AfterThrowing
配置切面和通知
// 配置了自动AOP代理的,需要在类上配置该注解,不然无法被识别为切面
@Aspect
public class MyAspect {// 异常通知@AfterThrowing(value = "execution(* com.pc.aop.dao.impl.CustomerDaoImpl.find(..))", throwing = "ex")// 通知:异常处理public void throwHandler(Throwable ex) {System.out.println("异常处理。。。。。。" + ex.getMessage());}
}
单元测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringAOPTest {// 注入依赖@Resource(name = "customerDao")private CustomerDao customerDao;// 测试异常通知@Testpublic void testAfterThrowing() {customerDao.find();}
}
输出
查询用户了。。。
异常处理。。。。。。/ by zero
最终通知
最终通知:无论目标方法是否出现异常总是执行的增强。
注解:@After
PS:该案例和异常测试案例对同一个target进行增强。
配置切面和通知
// 配置了自动AOP代理的,需要在类上配置该注解,不然无法被识别为切面
@Aspect
public class MyAspect {// 最终通知@After("execution(* com.pc.aop.dao.impl.CustomerDaoImpl.find(..))")// 通知:关闭资源public void close() {System.out.println("关闭资源。。。。。。");}
}
单元测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringAOPTest {// 注入依赖@Resource(name = "customerDao")private CustomerDao customerDao;// 测试最终通知@Testpublic void testFinally() {customerDao.find();}
}
输出
查询用户了。。。
关闭资源。。。。。。
异常处理。。。。。。/ by zero
切入点的注解
在上面的案例中,都是在通知上面直接定义切入点。这样有一个比较麻烦的问题,也就是如果我们需要修改多个通知相同的切入点,那么需要改大量的切入点代码。
上面的问题,可以通过使用切入点注解@Pointcut
解决。
案例:
package com.pc.aop.advice;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;/*** 切面类* * @author Switch* @data 2016年11月23日* @version V1.0*/
// 配置了自动AOP代理的,需要在类上配置该注解,不然无法被识别为切面
@Aspect
public class MyAspect {// 异常通知@AfterThrowing(value = "com.pc.aop.advice.MyAspect.pointcut1()", throwing = "ex")// 通知:异常处理public void throwHandler(Throwable ex) {System.out.println("异常处理。。。。。。" + ex.getMessage());}// 最终通知@After("com.pc.aop.advice.MyAspect.pointcut1()")// 通知:关闭资源public void close() {System.out.println("关闭资源。。。。。。");}// 配置切入点@Pointcut("execution(* com.pc.aop.dao.impl.CustomerDaoImpl.find(..))")public void pointcut1() {}
}
PS:切入点的注解需要定义在方法上,切入点方法一般是无意义的。如果需要使用切入点方法,只需要在通知声明中写入包名.类型.方法名()
,如果通知和切入点在一个类中,那么也可以直接写入方法名()
Spring AOP小项目
GitHub:Spring AOP小项目
GitHub:MyStore-netease
Spring AOP技术(基于AspectJ)的Annotation开发相关推荐
- Spring AOP技术(基于AspectJ)的XML开发
Spring AOP技术(基于AspectJ)的XML开发 @(Spring)[aop, spring, xml, Spring, annotation, aspectJ] Spring AOP技术基 ...
- Spring AOP之---基于JDK动态代理和CGLib动态代理的AOP实现
AOP(面向切面编程)是OOP的有益补充,它只适合那些具有横切逻辑的应用场合,如性能监测,访问控制,事物管理,日志记录等.至于怎么理解横切逻辑,敲完实例代码也就明白了. 为什么要使用AOP,举个栗子: ...
- 如何理解 Spring AOP 以及使用 AspectJ?
作者 | 阿文 责编 | 屠敏 出品 | CSDN(ID:CSDNnews) 在 Spring 中 AOP 是一个非常非常重要的概念,那么什么是AOP呢? AOP 即面向切面编程,也可以叫做面向方向编 ...
- Spring Aop实例之AspectJ注解配置
上篇博文<Spring Aop实例之xml配置>中,讲解了xml配置方式,今天来说说AspectJ注解方式去配置spring aop. 依旧采用的jdk代理,接口和实现类代码请参考上篇博文 ...
- 关于Spring AOP中切点修饰符@annotation、@args与args约束说明
前言 于其说这是一篇文章,不如说这是一篇笔记,主要介绍了@annotation.@args和args的作用以及一些坑点.这里主要记录一些项目用到的,没有成一套体系,网上其他文章对Spring AOP的 ...
- 简单好用!利用Spring AOP技术10分钟实现一个数据库读写分离方案
前言 最近我们的APP在线用户越来越多,接口的响应速度也是越来越慢,经过运维排查发现是由于并发查询太多导致的数据库压力比较大,架构师经过调研给出了数据库读写分离的解决方案,为了快速解决问题,我们最终采 ...
- 简单好用!利用Spring AOP技术10分钟实现一个读写分离方案
点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达今日推荐:2020年7月程序员工资统计,平均14357元,又跌了,扎心个人原创100W+访问量博客:点击前往,查看更多 作者 ...
- 【Spring AOP】基于注解的 AOP 编程
Spring AOP 基于注解的 AOP 编程的开发 开发步骤 切入点复用 切换动态代理的创建方式(JDK.Cglib) AOP 开发中的一个坑(业务方法互相调用) AOP 知识总结 更多内容请查看笔 ...
- 实例简述Spring AOP之对AspectJ语法的支持
Spring的AOP可以通过对@AspectJ注解的支持和在XML中配置来实现,本文通过实例简述如何在Spring中使用AspectJ. 一:使用AspectJ注解: 1,启用对AspectJ的支持: ...
最新文章
- php输出带的字符串吗,php输出含有“#”字符串的方法
- MATLAB常见语法错误分析及解决办法
- 【PAT (Advanced Level) Practice】1037 Magic Coupon (25 分)
- 028_jdbc-mysql大文本
- 前端如何实现音乐盒胶盘的转动_干货来袭!web前端开发工程师必看之如何使用CSS3实现瀑布流效果?...
- python解zuobiaoxi方程_滑坡稳定性分析程序初探---Python版!
- 学习hadoop需要什么基础
- HTTP 响应的分块传输
- python程序打包exe
- 一键安装lamp环境 centos
- spython_spython
- 一文读懂复权—不复权、前复权、后复权
- Unity3D世界坐标和局部坐标的关系,之间转换浅谈
- Guitar Pro8最新2023中文免费吉他乐谱作曲练习工具
- 程序员公众号用什么工具写?
- linux系统怎么连接显示器,Linux下笔记本外接显示器 · Eulerlee
- Java将OFD文件转PDF文件
- MemSQL性能测试结果
- 使用递归函数计算1到n之和
- Python解析html获取超链接地址并下载解析
热门文章
- idea的总部_Studio Didea新总部办公室,意大利 / Studio Didea
- 04737 c++ 自学考试2019版 第二章课后程序设计题 2
- 【Nginx那些事】nginx配置实例(三)动静分离
- NodeJs 的安装及配置环境变量
- 从头开始开发gis_DevRel工程师一:从头开始建立开发人员关系团队
- 亚马逊云服务开通指南_亚马逊弹性容器服务初学者指南
- Android获取通讯录速度,在android中获取联系人非常慢
- python怎么设计奥运五环_python 相关语法 图形绘制 奥运五环
- Linux编辑只读文件
- Common下MadieHelper.cs