1.AOP简单上手

AOP(Aspect Oriented Programming),意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。它通过对既有程序定义一个切入点,然后在其前后切入不同的执行内容,比如常见的有:打开数据库连接/关闭数据库连接、打开事务/关闭事务记录日志等。AOP可以降低耦合,把通用的业务提出来,提高代码的可重用性,同时提高开发的效率,使开发人员只关心真正的业务逻辑.

  1. 引入AOP的依赖
 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>

@EnableAspectJAutoProxy已经默认开启,不需要在启动类上添加.
       而当我们需要使用CGLIB来实现AOP的时候,需要配置spring.aop.proxy-target-class=true.但是注意:高版本spring自动根据运行类选择JDK或CGLIB代理,也就是当运行类没有继承接口,spring也会自动使用CGLIB代理。我们无需设置proxy-target-class属性,JDK动态代理是模拟接口实现的方式,cglib是模拟子类继承的方式,一般采用前者,因为前者效率高。

2 简单示例

@Aspect
@Component
public class LogAspect {@Around(value = "execution(* com.jun.test.microservice..*(..))")public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint){Object returnVal = null;final Logger log = getLog(proceedingJoinPoint);final String methodName = proceedingJoinPoint.getSignature().getName();try {final Object[] args = proceedingJoinPoint.getArgs();final String arguments;if (args == null || args.length == 0) {arguments = "";} else {arguments = Arrays.deepToString(args);}log.info("Entering method [" + methodName + " with arguments [" + arguments + "]");returnVal = proceedingJoinPoint.proceed();return returnVal;} catch (Throwable throwable) {throwable.printStackTrace();} finally {log.info("Leaving method [" + methodName + "] with return value [" + (returnVal != null ? returnVal.toString() : "null") + "].");}return null;}protected Logger getLog(final JoinPoint joinPoint) {final Object target = joinPoint.getTarget();if (target != null) {return LoggerFactory.getLogger(target.getClass());}return LoggerFactory.getLogger(getClass());}}

注意

1.当有多个切面针对同一个切点时,可以使用@order()来指定执行顺序,可以理解成多个同心圆,要执行的方法为圆心,最外层的order最小。从最外层按照AOP1、AOP2的顺序依次执行doAround方法,doBefore方法。然后执行method方法,最后按照AOP2、AOP1的顺序依次执行doAfter、doAfterReturn方法。也就是说对多个AOP来说,先before的,一定后after。

2.@Order的作用于可以在类,方法,字段上,但是他指定的是容器中bean的加载顺序.

2.自定义注解+AOP

可以通过自定义注解,来更针对性的定义切点.
2.1 首先自定义注解

@Target({ElementType.PARAMETER, ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemServiceLog {String description()  default "";
}

2.2 定义切面类
实现注有@SystemServiceLog的方法抛出异常时,记录日志。

@Aspect
@Component
public class AnnotationAspect {//Service层切点,拦截添加@SystemServiceLog的@Pointcut("@annotation(com.jun.test.microservice.aspect.SystemServiceLog)")public  void serviceAspect() {}@AfterThrowing(pointcut = "serviceAspect()", throwing = "e")public  void doAfterThrowing(JoinPoint joinPoint, Throwable e) {//获得request和sessionHttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();HttpSession session = request.getSession();//获取请求ipString ip = request.getRemoteAddr();//获取用户请求方法的参数并序列化为JSON格式字符串String params = "";if (joinPoint.getArgs() !=  null && joinPoint.getArgs().length > 0) {for ( int i = 0; i < joinPoint.getArgs().length; i++) {params += JsonUtils.object2Json(joinPoint.getArgs()[i]) + ";";}}Logger log = getLog(joinPoint);try {/*==========数据库日志=========*/log.info("异常处理");log.info(e.getMessage());log.info((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));log.info(params);log.info(ip);//保存数据库//logService.add(log);System.out.println("=====异常通知结束=====");}  catch (Exception ex) {//记录本地异常日志log.error("==异常通知异常==");log.error("异常信息:{}", ex.getMessage());}/*==========记录本地异常日志==========*/log.error("异常方法:{}异常信息:{}参数:{}", joinPoint.getTarget().getClass().getName() + joinPoint.getSignature().getName(), e.getMessage(), params);}protected Logger getLog(final JoinPoint joinPoint) {final Object target = joinPoint.getTarget();if (target != null) {return LoggerFactory.getLogger(target.getClass());}return LoggerFactory.getLogger(getClass());}}

2.3 在需要的方法上添加自定义注解

@Service
public class UsrServiceImpl implements IUserService {@SystemServiceLog(description = "查询用户")public UserAccount getUser(String id){int i = 0/0;return new UserAccount(id,"hello");}
}

以上即可.结合自定义注解和模板,可以实现很多方便的功能,如记录系统操作日志(添加,删除等等),记录异常等.对一些方法都有的逻辑可以提出来,如参数校验,限制访问频率等.

面向切面编程AOP的最佳入门示例相关推荐

  1. Spring in Action 入门之面向切面编程AOP

    注明:这篇文章一是当成学习笔记,二是给大家提供另一个快速理解学习Spring的参考.欢迎留言讨论,持续更新中~ (该部分是Spring的面向切面编程AOP) 第四章 通知Bean 在软件编程中,散布于 ...

  2. Spring-学习笔记08【面向切面编程AOP】

    Java后端 学习路线 笔记汇总表[黑马程序员] Spring-学习笔记01[Spring框架简介][day01] Spring-学习笔记02[程序间耦合] Spring-学习笔记03[Spring的 ...

  3. Spring之面向切面编程AOP(八)

    介绍&步骤 视频教程: https://www.bilibili.com/video/BV1WZ4y1P7Bp?p=121 官方笔记链接:https://pan.baidu.com/s/1dn ...

  4. 九、面向切面编程AOP

    本栏博客目录 一.Spring的IOC和DI 二.IoC和DI注解开发 三.SpringMVC入门 四.SpringMVC的请求和响应 五.JdbcTemplate 六.Spring练习 七.Spri ...

  5. 服务端第三次课程:面向切面编程AOP

    3:面向切面编程AOP 1:回顾 bean的组装方式 规划的装配 component autowired sacn是在configuration底下的 Java config 使用configurat ...

  6. Spring→面向切面编程AOP、相关概念、通知Advice类型、配置切面切入点通知、AOP相关API、AOP代理类ProxyFactoryBean、AOP注解@AspectJ

    面向切面编程AOP CGLib AOP相关概念 Advice类型 Spring实现AOP Spring配置切面aspect 配置切入点pointcut 配置通知advice 配置通知参数 调用新的父类 ...

  7. Spring(四):面向切面编程AOP

    2019独角兽企业重金招聘Python工程师标准>>> 横切关注点:分布于应用中多处的功能 面向切面编程AOP:将横切关注点与业务逻辑相分离 在使用面向切面编程时,仍在一个地方定义通 ...

  8. java切面编程 切面概念,面向切面编程(AOP)初探

    面向对象编程通过设计和语言本身提供的模块化.封装.继承.多态来实现软件复用.尽管OOP在建模以及实现复杂软件方面非常成功,它仍然有一些问题.面向切面编程(AOP)被认为是一项有前途的新技术,它通过对交 ...

  9. 【Spring】面向切面编程AOP

    AOP基础 什么是AOP [废话解释]在软件业,AOP全称Aspect Oriented Programming 即:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AO ...

最新文章

  1. .net 中 using的几种用法
  2. 第十六届全国大学生智能车讯飞智慧餐厅智能车竞赛比赛成绩
  3. tcp为什么需要3次握手和3次握手的过程
  4. 我的RSS我做主:My RSS
  5. 阻止页面电话号码变蓝
  6. idea git 整合使用
  7. 域名是什么_个人买域名有什么用?注册域名有哪些步骤?
  8. pip install requests_爬虫_Day 6 学习requests库这一篇文章足够
  9. java 怎么获取键的值_在 Java 中如何获取 Map 的所有键和值
  10. 为vs2008添加Mobile Web Forms模板
  11. ios版塔防类游戏源码
  12. mac清除ps缓存 mac系统存储空间清理
  13. Windows快捷键(三)—— 触摸板手势
  14. 【FLASH实例1000教程】(4)上
  15. 来自CSDN的精华网址
  16. 【数据分析实战】淘宝用户行为模式分析
  17. 计算机生成的精美图形,太震撼啦!!!
  18. 61、智能指针类模板
  19. 最短路径经典算法其二Bellman-Ford
  20. 速方云怎么下载keep2share文件?

热门文章

  1. mysql ibatis xml配置 like_iBatis学习方法及入门总结
  2. 基于modbus协议的工业自动化网络规范_工控学堂:解读Modbus通讯协议「宜收藏」...
  3. 手机进不了recovery模式了 怎么办
  4. mysql未提交事务sql_MySQL如何找出未提交事务的SQL浅析
  5. mybatis 时间_开发工具:Mybatis.Plus.插件三种方式的逆向工程
  6. c语言编程算法模板,C语言编程算法精选.doc
  7. 四十七、面试前,必须搞懂Java中的线程池ThreadPoolExecutor(上篇)
  8. 十六、深入Python字符串
  9. 浙江大学杭州国际科创中心招聘优秀青年人才(机器学习及大数据)
  10. 从EMD、WMD到WRD:文本向量序列的相似度计算