说明:
(1)本篇博客主要内容:Around Advice 环绕通知,这是最强大的通知,自定义通知执行时机,可决定目标方法是否运行。这是核心的,也是最重要的通知。
(2)虽然在【MyBatis进阶一:MyBatis日志管理;(【如何输出日志到日志文件中】待补充……)】介绍了日志的内容,但是如何把日志存放在一个日志文件中尚未接触;然后,估计日志还有很多其他内容尚不了解;所以,以后一定要较系统的了解下系统日志的内容;
(3)本篇博客的案例还是比较重要的,可以预估在以后的开发中,案例中的问题大概率会经常遇到;
目录
(1)pom.xml:引入所需依赖:【spring-context模块】,【aspectjweaver模块】
(2)创建applicationContext.xml配置文件:引入【默认命名空间】,【context命名空间】,【aop命名空间】;配置IoC容器中的bean;
三:正式实现:使用【Spring AOP技术】中的【Around Advice 环绕通知】去实现【零:需求说明】中的需求;
(1)创建容纳切面类的包:aspect包;添加用户检查方法运行效率的切面类:MethodChecker类;
(2)配置applicationContext.xml:配置究竟在【哪些类的哪些方法上】应用【MethodChecker切面类】;
(3)创建SpringApplication入口类,去测试;
零:需求说明
场景和需求:随着数据量的累计、用户量的增大,生产环境中系统越来越慢,如何定位到底是哪个方法执行慢?
问题分析:
● 这个问题看似简单,但实际上挺复杂的;因为,一个大型系统的类和方法可能有成千上万,我们肯定不能给每一个方法都增加代码去捕捉方法的执行时间,因为这样做效率会很差;
● 合适的策略:【Spring AOP】就是一个很好的方案;我们只需要在方法执行前捕捉方法的开始时间,方法执行后捕获方法的结束时间,然后就能算出方法的执行时间;如果方法的执行时间超过了规定范围,我们就将其输出保存在日志中;
● 因为这个场景下,我们要获取两个时间(运行前时间和运行后时间),可以知道AOP中的【前置通知、后置通知、返回后通知、异常通知】都不能解决这个问题;Spring提供了一个更强大的通知【Around Advice 环绕通知】,利用环绕通知,可以控制目标方法完整的运行周期;
一:准备一个工程,演示用;
为了演示,导入示例工程s01(这个工程在WorkSpace的aop目录下):
其中预置了readme.md,EmployeeDao,UserDao,EmployeeService,EmployeeDao;
(1)readme.md文档:
XML配置Sring AOP
(2)EmployeeDao类:
package com.imooc.spring.aop.dao; /** * 员工表Dao */ public class EmployeeDao { public void insert(){ System.out.println("新增员工数据"); } }
说明:
(1)这个类模拟了,操作数据中的Employee员工表; 其中添加了一个示意性的方法,向Employee员工表插入一条数据;
(3)UserDao类:
package com.imooc.spring.aop.dao; /** * 用户表Dao */ public class UserDao { public void insert(){ System.out.println("新增用户数据"); } }
说明:
(1)这个类模拟了,操作数据中User用户表; 其中添加了一个示意性的方法,向User用户表插入一条数据;
(4)EmployeeService类:
package com.imooc.spring.aop.service; import com.imooc.spring.aop.dao.EmployeeDao; /** * 员工服务 */ public class EmployeeService { private EmployeeDao employeeDao; public void entry(){ System.out.println("执行员工入职业务逻辑"); employeeDao.insert(); } public EmployeeDao getEmployeeDao() { return employeeDao; } public void setEmployeeDao(EmployeeDao employeeDao) { this.employeeDao = employeeDao; } }
说明:
(1)EmployeeService主要是处理员工入职的逻辑,其中会调用EmployeeDao中的方法;
(2)然后,其中的EmployeeDao属性,也生成了get和set方法;
(5)UserService类: