2、Spring之AOP
AOP术语
- 通知:定义了切面是什么以及何时使用。除了要描述页面要完成的工作,通知还解决了何时执行这个工作的问题。
- 连接点:连接点是一个物理的存在。这个点可以是调用方法时、抛出异常时、甚至是修改一个字段时。
- 切点:如果通知定义了切面是”什么“和”何时“,那么切点定义了”何处“。切点的定义会匹配通知所要织入的一个或者多个连接点。通常使用明确的类名和方法名来指定这些切点,或者使用正则表达式定义匹配的类和方法名模式来指定这些切点。
- 切面:切面是切点和通知的组合。
配置AOP
<!-- 配置切面的Bean -->
<bean id="loggingAspect" class="com.test.spring.aop.xml.LoggingAspect"></bean>
<bean id="validationAspect" class="com.test.spring.aop.xml.ValidationAspect"></bean>
<bean id ="constant" class="com.test.spring.aop.xml.ConstantImpl"></bean>
<!-- 配置AOP -->
<aop:config>
<!-- 配置切点表达式 -->
<aop:pointcut expression="execution(* com.test.spring.aop.xml.ArithmeticCalculator.*(..))" id="pointcut"/>
<!-- 配置切面和通知 -->
<aop:aspect ref="loggingAspect" order="2">
<aop:before method="beforeMethod" pointcut-ref="pointcut"/>
<aop:after-returning method="afterReturning" returning="result" pointcut-ref="pointcut"/>
<aop:after method="afterMethod" pointcut-ref="pointcut"/>
<aop:after-throwing method="afterThrowing" throwing="ex" pointcut-ref="pointcut"/>
<!--<aop:around method="aroundMethod" pointcut-ref="pointcut"/> -->
</aop:aspect>
<aop:aspect ref="validationAspect" order="1">
<aop:before method="validateArgs" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
LoggingAspect
public class LoggingAspect {
public void beforeMethod(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
//为通知传递参数,可以在JoinPoint 中拦截调用的目标方法,包括调用的目标方法的名字,出入目标方法的参数。
Object[] args = joinPoint.getArgs();
System.out.println("The method " + methodName + " begins with " + Arrays.asList(args));
}
public void afterMethod(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
System.out.println("The method " + methodName + " ends");
}
public void afterReturning(JoinPoint joinPoint, Object result) {
String methodName = joinPoint.getSignature().getName();
System.out.println("The method " + methodName + " ends with " + result);
}
public void afterThrowing(JoinPoint joinPoint, Exception ex) {
String methodName = joinPoint.getSignature().getName();
System.out.println("The method " + methodName + " occurs excetion:" + ex);
}
环绕通知
public Object aroundMethod(ProceedingJoinPoint pjd) {
Object result = null;
String methodName = pjd.getSignature().getName();
try {
// 前置通知
System.out.println("The method " + methodName + " begins with " + Arrays.asList(pjd.getArgs()));
// 执行目标方法
result = pjd.proceed();
// 返回通知
System.out.println("The method " + methodName + " ends with " + result);
} catch (Throwable e) {
// 异常通知
System.out.println("The method " + methodName + " occurs exception:" + e);
throw new RuntimeException(e);
}
// 后置通知
System.out.println("The method " + methodName + " ends");
return result;
}
通过切面引入新功能
<aop:aspect ref="loggingAspect" order="2">
<aop:declare-parents types-matching="com.test.spring.aop.xml.ArithmeticCalculator+"
implement-interface="com.test.spring.aop.xml.Constant" delegate-ref="constant"/>
</aop:aspect>
说明:通过切面引入新的功能就是为代理实现接口的一个过程。ArithmeticCalculator
是一个代理,通过<aop:declare-parents/>
为此代理实现Constant
接口,并指定默认实现delegate-ref="constant"
从而达到扩展基础对象ArithmeticCalculator
的效果。在掉用目标Bean的时候,如果不是目标Bean的方法,则从代理的实现的接口constant
寻找方法的代用,如果是目标Bean的方法,则调用目标Bean的方法。
注解使用
启用注解: <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
/**
* 可以使用 @Order 注解指定切面的优先级, 值越小优先级越高
*/
@Order(1)
@Aspect
@Component
public class LoggingAspect {
/**
* 定义一个方法, 用于声明切入点表达式. 一般地, 该方法中再不需要添入其他的代码.
* 使用 @Pointcut 来声明切入点表达式.
* 后面的其他通知直接使用方法名来引用当前的切入点表达式.
*/
@Pointcut("execution(public int com.spring.aop.ArithmeticCalculator.*(..))")
public void declareJointPointExpression(){}
/**
* 在 com.spring.aop.ArithmeticCalculator 接口的每一个实现类的每一个方法开始之前执行一段代码
*/
@Before("declareJointPointExpression()")
public void beforeMethod(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
Object [] args = joinPoint.getArgs();
System.out.println("The method " + methodName + " begins with " + Arrays.asList(args));
}
/**
* 在方法执行之后执行的代码. 无论该方法是否出现异常
*/
@After("declareJointPointExpression()")
public void afterMethod(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
System.out.println("The method " + methodName + " ends");
}
/**
* 在方法法正常结束受执行的代码
* 返回通知是可以访问到方法的返回值的!
*/
@AfterReturning(value="declareJointPointExpression()",
returning="result")
public void afterReturning(JoinPoint joinPoint, Object result){
String methodName = joinPoint.getSignature().getName();
System.out.println("The method " + methodName + " ends with " + result);
}
/**
* 在目标方法出现异常时会执行的代码.
* 可以访问到异常对象; 且可以指定在出现特定异常时在执行通知代码
*/
@AfterThrowing(value="declareJointPointExpression()",
throwing="e")
public void afterThrowing(JoinPoint joinPoint, Exception e){
String methodName = joinPoint.getSignature().getName();
System.out.println("The method " + methodName + " occurs excetion:" + e);
}
/**
* 环绕通知需要携带 ProceedingJoinPoint 类型的参数.
* 环绕通知类似于动态代理的全过程: ProceedingJoinPoint 类型的参数可以决定是否执行目标方法.
* 且环绕通知必须有返回值, 返回值即为目标方法的返回值
*/
@Around("execution(public int com.spring.aop.ArithmeticCalculator.*(..))")
public Object aroundMethod(ProceedingJoinPoint pjd){
Object result = null;
String methodName = pjd.getSignature().getName();
try {
//前置通知
System.out.println("The method " + methodName + " begins with " + Arrays.asList(pjd.getArgs()));
//执行目标方法
result = pjd.proceed();
//返回通知
System.out.println("The method " + methodName + " ends with " + result);
} catch (Throwable e) {
//异常通知
System.out.println("The method " + methodName + " occurs exception:" + e);
throw new RuntimeException(e);
}
//后置通知
System.out.println("The method " + methodName + " ends");
return result;
}
}
2、Spring之AOP的更多相关文章
- Spring基于AOP的事务管理
Spring基于AOP的事务管理 事务 事务是一系列动作,这一系列动作综合在一起组成一个完整的工作单元,如果有任何一个动作执行失败,那么事务 ...
- Spring实现AOP的4种方式
了解AOP的相关术语:1.通知(Advice):通知定义了切面是什么以及何时使用.描述了切面要完成的工作和何时需要执行这个工作.2.连接点(Joinpoint):程序能够应用通知的一个“时机”,这些“ ...
- spring的AOP
最近公司项目中需要添加一个日志记录功能,就是可以清楚的看到谁在什么时间做了什么事情,因为项目已经运行很长时间,这个最初没有开来进来,所以就用spring的面向切面编程来实现这个功能.在做的时候对spr ...
- Spring(五)AOP简述
一.AOP简述 AOP全称是:aspect-oriented programming,它是面向切面编号的思想核心, AOP和OOP既面向对象的编程语言,不相冲突,它们是两个相辅相成的设计模式型 AOP ...
- Spring中AOP原理,源码学习笔记
一.AOP(面向切面编程):通过预编译和运行期动态代理的方式在不改变代码的情况下给程序动态的添加一些功能.利用AOP可以对应用程序的各个部分进行隔离,在Spring中AOP主要用来分离业务逻辑和系统级 ...
- Spring之AOP面向切片
一.理论基础: AOP(Aspectoriented programming)面向切片/服务的编程,在Spring中使用最多的是对事物的处理.而AOP这种思想在程序中很多地方可以使用的,比如说, ...
- 利用CGLib实现动态代理实现Spring的AOP
当我们用Proxy 实现Spring的AOP的时候, 我们的代理类必须实现了委托类的接口才能实现. 而如果代理类没有实现委托类的接口怎么办? 那么我们就可以通过CGLib来实现 package cn. ...
- spring之aop概念和配置
面向切面的一些概念: 简单说: 连接点就一些方法,在这些方法基础上需要额外的一些业务需求处理. 切入点就是方法所代表的功能点组合起来的功能需求. 通知就是那些额外的操作. 织入就是使用代理实现整个切入 ...
- Spring的AOP与代理
spring 支持两种注入方式: setter/constructor 支持多种配置方式: xml/java5注解/java类配置 支持两种事务管理: 声明性/编程性 实际上上述方式只有一个就能保证系 ...
- Spring 实践 -AOP
Spring 实践 标签: Java与设计模式 AOP引介 AOP(Aspect Oriented Programing)面向切面编程采用横向抽取机制,以取代传统的纵向继承体系的重复性代码(如性能监控 ...
随机推荐
- centos7用docker安装kafka
参考之前的文章安装zookeeper集群 https://www.cnblogs.com/xiaohanlin/p/10124674.html 如果是测试环境也可以简单安装单节点的zookeeper ...
- 宽带、ADSL、以太网、PPPoE
作者:北极链接:https://www.zhihu.com/question/25847423/answer/31563282来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出 ...
- c语言数据结构学习心得——队列
队列 只允许在一端进行插入,在另一端进行删除的线性表 队头(Front):允许删除的一端(队首) 队尾(Rear):允许插入的一端 FIFO:先进先出 不要求从数组首位开始存储队列 #define M ...
- [golang] go的typeswitch guard(类型区别)语法和type assertion(类型断言)语法
最近在实现golang,看到个go的特性语法: typeswitch guard. typeswitch guard语法如下: package main import "fmt" ...
- 最大子树和 树形dp
题目描述 小明对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题.一天他早晨骑车去上课,路上见到一个老伯正在修剪花花草草,顿时想到了一个有关修剪花卉的问题.于是当日课后,小明 ...
- tomcat更改web文件路径
由于代码太长,记不住!只能自己做个小笔记了!! <Context path="/" docBase="/opt/appl/merch.bak" debug ...
- [DEBUG]-[org.mybatis.spring.SqlSessionFactoryBean.buildSqlSessionFactory(SqlSessionFactoryBean.java:431)] 一直在创建sqlsession工厂原因
今天在做开发项目的时候出现一直在控台输出创建sqlsessionfactory'这个代码, tomcat一直在控制台上输出这个内容无法停止下来,那么到底是什么原因呢, 我们可以在输出信息上看到有个wa ...
- svn学习笔记(二)
一.TortoiseSVN日常使用 1.1 浏览仓库 Repo-browser : 浏览仓库中资源信息 1.2 导入导出 Export :导出项目 ,和checkout区别 (checkout检出后文 ...
- HDU-6341 Problem J. Let Sudoku Rotate(dfs 剪枝)
题目:有一个4*4*4*4的数独,每一横每一竖每一个小方块中都无重复的字母,即都为0-9,A-F..有一个已经填好的数独,若干个4*4的方块被逆时针拧转了若干次,问拧转回来至少需要多少次. 分析:很明 ...
- UVA - 10125 哈希
题意:求集合中最大的\(d\)使得\(a+b=d-c\) 学习一下哈希的姿势(原来所谓链地址法就是直接跑个图啊) 哈希真有趣,全靠xjb乱搞 就叫这套hash为xjb-fibonacci-lpy-ha ...