017-Spring Boot AOP
一、概述
面向切面编程,将业务代码与处理琐碎相关度少的代码隔离开。以便达到重用,解耦。
用途:日志记录、权限处理、性能统计、监控、事务处理、异常处理等
通知类型有:前置通知、后置最终通知、后置返回通知、后置异常通知、环绕通知,
二、使用
1》增加POM依赖,默认已经启用aop,不需要增加注解等
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2》创建一个Aspect切面类,并指定切点::
封装横切关注点(日志,监控等),需要配置通知(前置通知,后置通知)和切入点(那些包哪些类的哪些方法等)
@Aspect
@Component
public class LogAspect {
// 配置了com.lhx.spring.springboot.dao包及其子包下的所有类的所有方法
@Before("execution (* com.lhx.spring.springboot.dao..*.*(..))")
public void executeService() {
System.out.println("method executeService done");
}
}
2.1》前置通知 Before
/**
* 前置通知,方法调用前被调用
* @param joinPoint
*/
@Before("executeService()")
public void doBeforeAdvice(JoinPoint joinPoint){
System.out.println("我是前置通知!!!");
//获取目标方法的参数信息
Object[] obj = joinPoint.getArgs();
//AOP代理类的信息
joinPoint.getThis();
//代理的目标对象
joinPoint.getTarget();
//用的最多 通知的签名
Signature signature = joinPoint.getSignature();
//代理的是哪一个方法
System.out.println(signature.getName());
//AOP代理类的名字
System.out.println(signature.getDeclaringTypeName());
//AOP代理类的类(class)信息
signature.getDeclaringType();
//获取RequestAttributes
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
//从获取RequestAttributes中获取HttpServletRequest的信息
HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
//如果要获取Session信息的话,可以这样写:
//HttpSession session = (HttpSession) requestAttributes.resolveReference(RequestAttributes.REFERENCE_SESSION);
Enumeration<String> enumeration = request.getParameterNames();
Map<String,String> parameterMap = Maps.newHashMap();
while (enumeration.hasMoreElements()){
String parameter = enumeration.nextElement();
parameterMap.put(parameter,request.getParameter(parameter));
}
String str = JSON.toJSONString(parameterMap);
if(obj.length > 0) {
System.out.println("请求的参数信息为:"+str);
}
}
注意:这里用到了JoinPoint和RequestContextHolder。通过JoinPoint可以获得通知的签名信息,如目标方法名、目标方法参数信息等。通过RequestContextHolder来获取请求信息,Session信息。
2.2》后置返回通知
/**
* 后置返回通知
* 这里需要注意的是:
* 如果参数中的第一个参数为JoinPoint,则第二个参数为返回值的信息
* 如果参数中的第一个参数不为JoinPoint,则第一个参数为returning中对应的参数
* returning 限定了只有目标方法返回值与通知方法相应参数类型时才能执行后置返回通知,否则不执行,对于returning对应的通知方法参数为Object类型将匹配任何目标返回值
* @param joinPoint
* @param keys
*/
@AfterReturning(value = "execution(* com.lhx.spring.springboot.dao..*.*(..))",returning = "keys")
public void doAfterReturningAdvice1(JoinPoint joinPoint,Object keys){
System.out.println("第一个后置返回通知的返回值:"+keys);
} @AfterReturning(value = "execution(* com.lhx.spring.springboot.dao..*.*(..))",returning = "keys",argNames = "keys")
public void doAfterReturningAdvice2(String keys){
System.out.println("第二个后置返回通知的返回值:"+keys);
}
调用方法
public String testAfterReturning(String key){
return "key=: "+key;
}
public Integer testAfterReturning01(Integer key){
return key;
}
当入参key=testsss时
第一个后置返回通知的返回值:key=: testsss
第二个后置返回通知的返回值:key=: testsss
当入参key=55553时
第一个后置返回通知的返回值:55553
2.3》后置异常通知
/**
* 后置异常通知
* 定义一个名字,该名字用于匹配通知实现方法的一个参数名,当目标方法抛出异常返回后,将把目标方法抛出的异常传给通知方法;
* throwing 限定了只有目标方法抛出的异常与通知方法相应参数异常类型时才能执行后置异常通知,否则不执行,
* 对于throwing对应的通知方法参数为Throwable类型将匹配任何异常。
* @param joinPoint
* @param exception
*/
@AfterThrowing(value = "executeService()",throwing = "exception")
public void doAfterThrowingAdvice(JoinPoint joinPoint,Throwable exception){
//目标方法名:
System.out.println(joinPoint.getSignature().getName());
if(exception instanceof NullPointerException){
System.out.println("发生了空指针异常!!!!!");
}
}
2.4》后置最终通知
/**
* 后置最终通知(目标方法只要执行完了就会执行后置通知方法)
* @param joinPoint
*/
@After("executeService()")
public void doAfterAdvice(JoinPoint joinPoint){ System.out.println("后置通知执行了!!!!");
}
2.5》环绕通知
/**
* 环绕通知:
* 环绕通知非常强大,可以决定目标方法是否执行,什么时候执行,执行时是否需要替换方法参数,执行完毕是否需要替换返回值。
* 环绕通知第一个参数必须是org.aspectj.lang.ProceedingJoinPoint类型
*/
@Around("executeService()")
public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint){
System.out.println("环绕通知的目标方法名:"+proceedingJoinPoint.getSignature().getName());
try {
Object obj = proceedingJoinPoint.proceed();
return obj;
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return null;
}
三、AOP配置项
打开spring-boot-autoconfigure-1.5.9.RELEASE.jar查看包org.springframework.boot.autoconfigure.aop。AopAutoConfiguration
配置项:spring.aop.auto
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
spring.aop.auto=true【默认】含义:启用aop
配置项:spring.aop.auto.proxy-target-class
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = true)
spring.aop.auto.proxy-target-class=false【默认】,含义:启用JdkDynamicAutoProxyConfiguration动态代理,代理接口,不能代理类
注意如果代理的是类会自动切换至CglibAutoProxyConfiguration代理
spring.aop.auto.proxy-target-class=true,含义:启用CglibAutoProxyConfiguration动态代理,代理接口和类
四、配置参数
1、默认也提供了:@EnableAspectJAutoProxy注解
有两个参数:代理方式:proxyTargetClass 默认false,与上文一致
exposeProxy:获取代理后对象,默认false。不支持。如果是true,可以通过AopContext.currentProxy()获取
2、后置注解增加参数
@Before("execution (* com.lhx.spring.springboot.dao..*.*(..))")
public void logAfter(JoinPoint point) {
System.out.println("after log done," + point.getTarget().getClass()
+ ",args=" + Arrays.asList(point.getArgs())
+",method="+point.getSignature());
}
017-Spring Boot AOP的更多相关文章
- Spring Boot AOP解析
Spring Boot AOP 面向切面编程(AOP)通过提供另一种思考程序结构的方式来补充面向对象编程(OOP). OOP中模块化的关键单元是类,而在AOP中,模块化单元是方面. AOP(Aspec ...
- Spring Boot AOP之对请求的参数入参与返回结果进行拦截处理
Spring Boot AOP之对请求的参数入参与返回结果进行拦截处理 本文链接:https://blog.csdn.net/puhaiyang/article/details/78146620 ...
- 玩转spring boot——AOP与表单验证
AOP在大多数的情况下的应用场景是:日志和验证.至于AOP的理论知识我就不做赘述.而AOP的通知类型有好几种,今天的例子我只选一个有代表意义的“环绕通知”来演示. 一.AOP入门 修改“pom.xml ...
- Spring Boot - AOP(面向切面)
AOP 全称 Aspect Oriented Programming(面向切面),AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分 ...
- spring boot aop打印http请求回复日志包含请求体
一.引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- Spring boot AOP 记录请求日志
如何将所有的通过url的请求参数以及返回结果都输出到日志中? 如果在controller的类中每个方法名都写一个log输出肯定是不明智的选择. 使用spring的AOP功能即可完成. 1. 在pom. ...
- redis分布式锁-spring boot aop+自定义注解实现分布式锁
接这这一篇redis分布式锁-java实现末尾,实现aop+自定义注解 实现分布式锁 1.为什么需要 声明式的分布式锁 编程式分布式锁每次实现都要单独实现,但业务量大功能复杂时,使用编程式分布式锁无疑 ...
- Spring Boot AOP 扫盲,实现接口访问的统一日志记录
AOP 是 Spring 体系中非常重要的两个概念之一(另外一个是 IoC),今天这篇文章就来带大家通过实战的方式,在编程猫 SpringBoot 项目中使用 AOP 技术为 controller 层 ...
- Spring Boot AOP
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是Spring框架中的一个重要内容,它通 ...
- Spring boot Aop 示例
需要的依赖 <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -- ...
随机推荐
- php对象序列化和cookie的问题,反序列化false
php对象序列化和cookie的问题,反序列化false $searchKeywords = array("羊奶","肥皂"); $searchKeywords ...
- springmvc中action跳转
return "redirect:/activity/listactivity.htm";
- Consul实现原理系列文章2: 用Gossip来做集群成员管理和消息广播
工作中用到了Consul来做服务发现,之后一段时间里,我会陆续发一些文章来讲述Consul实现原理.这篇文章会讲述Consul是如何使用Gossip来做集群成员管理和消息广播的. Consul使用Go ...
- eclipse启动不起来,eclipse.ini配置问题(支持大内存64bit问题)
Eclipse 启动不起来异常:JVM terminated. Exit code=-1 Eclipse 启动不起来,出现以下错误: JVM terminated. Exit code=-1-Xms4 ...
- 通过Get方式传递数据
1:因为get传参数有个特点就是不能超过256字节.如果数据大的话会溢出. 解决办法: $data=json_encode($data_array); 然后在拼接超链接: <a href=&qu ...
- mysql 京东
DROP TABLE IF EXISTS `jd_admin`;CREATE TABLE `jd_admin` ( `id` int(10) unsigned NOT NULL AUTO_INCREM ...
- easyui data-options的使用
easyui data-options的使用 data-options是jQuery Easyui 最近两个版本才加上的一个特殊属性.通过这个属性,我们可以对easyui组件的实例化可以完全写入到ht ...
- 【转】Monkey测试6-Monkey Test Log
Moneky Test Log 分析: 首先用一个最简单的例子分析:monkey --pct-trackball 0 --throttle 100 -v 500/*p参数: 表示指定测试的程序/*v参 ...
- 【转】 Monkey测试1——Monkey的使用
前言: 最近开始研究Android自动化测试方法,对其中的一些工具.方法和框架做了一些简单的整理,其中包括android测试框架.CTS.Monkey.Monkeyrunner.benchmark.其 ...
- ThinkPHP自动填充实现无限级分类的方法
这篇文章主要介绍了ThinkPHP自动填充实现无限级分类的方法,是ThinkPHP项目开发中非常实用的一个技巧,需要的朋友可以参考下 本文实例展示了ThinkPHP自动填充实现无限级分类的方法,是 ...