spring之AOP(面向切面编程)
2016-12-26 00:00
459 查看
一、简介
何为AOP,通俗的将就是给某些方法执行之前、执行之后等动作发生的时候执行某些操作,在执行这些操作的时候可以获取执行方法的相关信息,简化程序开发中总是重复的东西,比如方法入参出参的日志打印,用户访问权限校验,事务控制等。
二、术语
通知(advice):切面的工作被称为通知。通俗点:什么时候怎么干啥事。
1.前置通知(before):在目标方法被调用之前调用通知功能。
2.后置通知(after):在目标方法完成之后调用通知,此事不会关心方法的输出是什么。
3.返回通知(after-returning):在目标方法成功执行之后调用通知。
4.异常通知(after-throwing):在目标方法跑出异常后调用通知。
5.环绕通知(around):通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为。
连接点(joinpoint):使用通知的地方。
切点(pointcut):匹配通知所要织入的一个或多个连接点。
切面(aspect):通知和切点的结合定义切面的全部内容,它是什么,在何时何处完成其功能。
引入(introduction):可以向现有的类添加新方法和属性。
织入(weaving):把切面应用到目标对象并创建新的代理对象的过程。切面在制定的连接点被织入到目标对象中,在目标对象的生命周期里有多个点可以织入:
1.编译期:切面在目标类编译时织入,这种方式需要特殊的编译器,AspectJ的织入编辑器就是以这种方式织入切面的。
2.类加载期:切面在目标类加载到JVM时织入,这种方式需要特殊的类加载器(ClassLoader),它可以在目标类被引入应用之前增强该目标类的字节码。
3.运行期:切面在应用运行的某个时刻被织入,一般情况下,在织入切面时,AOP容器会为目标对象动态的创建一个代理对象,SpringAOP就是以这种方式织入切面的。
三、spring对AOP的支持
spring提供了4种类型的AOP支持:
1.基于代理的经典SpringAOP
2.纯POJO切面
3.@AspectJ注解驱动的切面
4.注入式AspectJ切面
前三种是springAOP实现的变体,SpringAOP构建在动态代理的基础之上,因此,spring对AOP的支持局限于方法拦截。
四、spring只支持方法界别的连接点
因为spring是基于动态代理,所以孩子恩能够支持方法级别的aop。AspectJ和JBoss,除了方法切点,还提供了字段和构造器接入点。spring缺少字段连接点的支持,无法让我们创建细粒度的通知,例如拦截对象字段的修改,而且他不支持构造器连接点,我们就无法再bean创建时应用通知。
五、切点表达式
execution(* sundsystem.CompactDisc.playTrack(int))
第一个* 返回任意类型
sundsystem.CompactDisc 方法所属的类型
playTrack 方法
int 接受int类型的参数
六、demo
注解:
何为AOP,通俗的将就是给某些方法执行之前、执行之后等动作发生的时候执行某些操作,在执行这些操作的时候可以获取执行方法的相关信息,简化程序开发中总是重复的东西,比如方法入参出参的日志打印,用户访问权限校验,事务控制等。
二、术语
通知(advice):切面的工作被称为通知。通俗点:什么时候怎么干啥事。
1.前置通知(before):在目标方法被调用之前调用通知功能。
2.后置通知(after):在目标方法完成之后调用通知,此事不会关心方法的输出是什么。
3.返回通知(after-returning):在目标方法成功执行之后调用通知。
4.异常通知(after-throwing):在目标方法跑出异常后调用通知。
5.环绕通知(around):通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为。
连接点(joinpoint):使用通知的地方。
切点(pointcut):匹配通知所要织入的一个或多个连接点。
切面(aspect):通知和切点的结合定义切面的全部内容,它是什么,在何时何处完成其功能。
引入(introduction):可以向现有的类添加新方法和属性。
织入(weaving):把切面应用到目标对象并创建新的代理对象的过程。切面在制定的连接点被织入到目标对象中,在目标对象的生命周期里有多个点可以织入:
1.编译期:切面在目标类编译时织入,这种方式需要特殊的编译器,AspectJ的织入编辑器就是以这种方式织入切面的。
2.类加载期:切面在目标类加载到JVM时织入,这种方式需要特殊的类加载器(ClassLoader),它可以在目标类被引入应用之前增强该目标类的字节码。
3.运行期:切面在应用运行的某个时刻被织入,一般情况下,在织入切面时,AOP容器会为目标对象动态的创建一个代理对象,SpringAOP就是以这种方式织入切面的。
三、spring对AOP的支持
spring提供了4种类型的AOP支持:
1.基于代理的经典SpringAOP
2.纯POJO切面
3.@AspectJ注解驱动的切面
4.注入式AspectJ切面
前三种是springAOP实现的变体,SpringAOP构建在动态代理的基础之上,因此,spring对AOP的支持局限于方法拦截。
四、spring只支持方法界别的连接点
因为spring是基于动态代理,所以孩子恩能够支持方法级别的aop。AspectJ和JBoss,除了方法切点,还提供了字段和构造器接入点。spring缺少字段连接点的支持,无法让我们创建细粒度的通知,例如拦截对象字段的修改,而且他不支持构造器连接点,我们就无法再bean创建时应用通知。
五、切点表达式
execution(* sundsystem.CompactDisc.playTrack(int))
第一个* 返回任意类型
sundsystem.CompactDisc 方法所属的类型
playTrack 方法
int 接受int类型的参数
六、demo
注解:
package com.pz.aop; 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; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import com.alibaba.fastjson.JSON; @Aspect @Component public class LogAspect { private static Logger logger = LoggerFactory.getLogger(LogAspect.class); @Pointcut("execution(public * com.pz.service..*.*(..))") public void logPoint(){} @Before("logPoint()") public void logBefor(JoinPoint joinPoint){ String method = joinPoint.getSignature().getName(); Object [] args = joinPoint.getArgs(); String param = JSON.toJSONString(args); logger.info("[前置通知][{}] param:{}", method, param); } @After("logPoint()") public void logAfter(JoinPoint joinPoint){ String method = joinPoint.getSignature().getName(); Object [] args = joinPoint.getArgs(); String param = JSON.toJSONString(args); logger.info("[后置通知][{}] result:{}", method, param); } @AfterReturning(pointcut="logPoint()", returning="result") public void logAfterReturning(JoinPoint joinPoint, Object result){ String method = joinPoint.getSignature().getName(); String response = JSON.toJSONString(result); logger.info("[返回通知][{}] return:{}", method, response); } @AfterThrowing(pointcut="logPoint()", throwing="e") public void logAfterThrowing(JoinPoint joinPoint, Exception e){ String method = joinPoint.getSignature().getName(); logger.error("[异常通知][{}] exception:{}", method, e.getMessage()); } @Around("logPoint()") public Object logArount(ProceedingJoinPoint pjp) throws Throwable{ Object result = null; String param = JSON.toJSONString(pjp.getArgs()); String method = pjp.getSignature().getName(); try{ logger.info("[环绕通知][{}] param:{}", method, param); result = pjp.proceed(); logger.info("[环绕通知][{}] result:{}", method, JSON.toJSON(result)); }catch(Exception e){ logger.error("[环绕通知][{}] exception:{}", method, e.getMessage()); throw new RuntimeException(e); } logger.info("[环绕通知][{}] return:{}", method, JSON.toJSON(result)); return result; } }
相关文章推荐
- Spring AOP面向切面编程
- Spring学习(六)-面向切面编程(AOP)
- spring实战-基于注解的面向切面编程(AOP)
- Spring之注解实现aop(面向切面编程)
- spring面向切面编程(AOP)的理解(转载)
- spring的AOP面向切面编程
- Spring AOP(面向切面编程)【AOP中的术语】
- 【spring源码学习】spring的AOP面向切面编程的实现解析
- Spring AOP 面向切面编程
- Spring基础学习(八)——AOP面向切面编程
- spring framework面向切面编程示例(xml配置):spring-aop
- Spring-aop面向切面编程
- Spring AOP面向切面编程
- spring 中的aop面向切面编程
- Aop_面向切面编程(2)_spring的aop实现
- SSM框架 之 Spring-AOP(面向切面编程)
- Spring之AOP面向切面编程实现(一)
- Spring AOP(面向切面编程)【AOP快速入门】
- 简单理解Spring中AOP(面向切面编程)
- Spring之AOP实现面向切面编程