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)面向切面编程采用横向抽取机制,以取代传统的纵向继承体系的重复性代码(如性能监控 ...
随机推荐
- NetworkX初相识
听说NetworkX是一个很牛的复杂网络研究的工具,就来试一下吧. import networkx as nx G= nx.Graph()#建立一个空白的图 G.add_node("node ...
- 深度学习TensorFlow常用函数
tensorflow常用函数 TensorFlow 将图形定义转换成分布式执行的操作, 以充分利用可用的计算资源(如 CPU 或 GPU.一般你不需要显式指定使用 CPU 还是 GPU, Tensor ...
- pg_basebackup命令解析
pg_basebackup命令首先解析输入的参数,再调用BaseBackup()函数进行备份处理. 在BaseBackup()函数内部,会首先传送WAL日志(如果指定了-x选项的话).随后依次遍历所有 ...
- Unity---动画系统学习(5)---使用MatchTarget来匹配动画
1. 介绍 做好了走.跑.转弯后,我们就需要来点更加高级的动画了. 我们使用自带动画学习笔记2中的FQVault动画,来控制人物FQ. 在动画学习笔记4的基础上添加Vault动画. 添加一个参数Vau ...
- 当AVPlayer在被释放之后,Player一直监听的时间没有被移除,提示错误的解决办法
Xcode Consolu打印出来的提示: An instance 0x156608c0 of class AVPlayer was deallocated while key value obser ...
- [AHOI2009]中国象棋 BZOJ1801 dp
题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方式是 ...
- docker load error: open /var/lib/docker/tmp/docker-import-347673752/bin/json: no such file or directory
docker save 对应 docker load docker export 对应 docker import 在导出的包的环境中的docker版本跟需要导入的环境中的docker版本不一致也可能 ...
- 洛谷 P4568 [JLOI2011]飞行路线
题目描述 Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的 ...
- Myeclipse经常弹出Subversion Native Library Not Available
- yii2 表单输入框设置
<?= $form->field($userRole, 'userid', ['options' =>['class' => 'bigDiv'] ])->textInpu ...