SpringAOP浅析
1、问题

问题:想要添加日志记录、性能监控、安全监测
2、最初解决方案
2.1、最初解决方案

2.2、抽象类进行共性设计,子类进行个性设计,此处不讲解,缺点一荣俱荣,一损俱损
2.3、使用装饰器模式/代理模式改进的解决方案

- public class MyInvocationHandler implements InvocationHandler {
- private Object target;
- public MyInvocationHandler(Object target) {
- this.target = target;
- }
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- //1.记录日志 2.时间统计开始 3.安全检查
- Object retVal = method.invoke(target, args);
- //4.时间统计结束
- return retVal;
- }
- public static Object proxy(Object target) {
- return Proxy.newProxyInstance(target.getClass().getClassLoader(),
- target.getClass().getInterfaces(), new MyInvocationHandler(target));
- }
- }
public class MyInvocationHandler implements InvocationHandler {
private Object target;
public MyInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//1.记录日志 2.时间统计开始 3.安全检查
Object retVal = method.invoke(target, args);
//4.时间统计结束
return retVal;
}
public static Object proxy(Object target) {
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), new MyInvocationHandler(target));
}
}
编程模型
- //proxy 在其上调用方法的代理实例
- //method 拦截的方法
- //args 拦截的参数
- Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- Object retVal=null;
- //预处理
- //前置条件判断
- boolean ok = true;
- if(!ok) {//不满足条件
- throw new RuntimeException("你没有权限");
- }
- else {//反射调用目标对象的某个方法
- retVal = method.invoke(target, args);
- }
- //后处理
- return retVal;
- }
//proxy 在其上调用方法的代理实例
//method 拦截的方法
//args 拦截的参数
Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object retVal=null;
//预处理
//前置条件判断
boolean ok = true;
if(!ok) {//不满足条件
throw new RuntimeException("你没有权限");
}
else {//反射调用目标对象的某个方法
retVal = method.invoke(target, args);
}
//后处理
return retVal;
}
缺点:使用麻烦,不能代理类,只能代理接口
- public class MyInterceptor implements MethodInterceptor {
- private Object target;
- public MyInterceptor(Object target) {
- this.target = target;
- }
- @Override
- public Object intercept(Object proxy, Method method, Object[] args,
- MethodProxy invocation) throws Throwable {
- //1.记录日志 2.时间统计开始 3.安全检查
- Object retVal = invocation.invoke(target, args);
- //4.时间统计结束
- return retVal;
- }
- public static Object proxy(Object target) {
- return Enhancer.create(target.getClass(), new MyInterceptor(target));
- }
- }
public class MyInterceptor implements MethodInterceptor {
private Object target;
public MyInterceptor(Object target) {
this.target = target;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy invocation) throws Throwable {
//1.记录日志 2.时间统计开始 3.安全检查
Object retVal = invocation.invoke(target, args);
//4.时间统计结束
return retVal;
}
public static Object proxy(Object target) {
return Enhancer.create(target.getClass(), new MyInterceptor(target));
}
}
编程模型
- //proxy 在其上调用方法的代理实例 method拦截的方法 args 拦截的参数
- //invocation 用来去调用被代理对象方法的
- @Override
- public Object intercept(Object proxy, Method method, Object[] args,
- MethodProxy invocation) throws Throwable {
- //预处理
- //前置条件判断
- boolean ok = true;
- if(!ok) {//不满足条件
- throw new RuntimeException("出错了");
- }
- else {//调用目标对象的某个方法
- Object retVal = invocation.invoke(target, args);
- }
- //后处理
- return retVal;
- }
//proxy 在其上调用方法的代理实例 method拦截的方法 args 拦截的参数
//invocation 用来去调用被代理对象方法的
@Override
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy invocation) throws Throwable {
//预处理
//前置条件判断
boolean ok = true;
if(!ok) {//不满足条件
throw new RuntimeException("出错了");
}
else {//调用目标对象的某个方法
Object retVal = invocation.invoke(target, args);
}
//后处理
return retVal;
}
动态代理本质


- @Aspect
- public class PayEbiAspect {
- @Pointcut(value="execution(* pay(..))")
- public void pointcut() {}
- @Around(value="pointcut()")
- public Object around(ProceedingJoinPoint pjp) throws Throwable {
- //1.记录日志
- //2.时间统计开始
- //3.安全检查
- Object retVal = pjp.proceed();//调用目标对象的真正方法
- //4.时间统计结束
- return retVal;
- }
- }
@Aspect
public class PayEbiAspect {
@Pointcut(value="execution(* pay(..))")
public void pointcut() {}
@Around(value="pointcut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
//1.记录日志
//2.时间统计开始
//3.安全检查
Object retVal = pjp.proceed();//调用目标对象的真正方法
//4.时间统计结束
return retVal;
}
}
- //2 切入点
- @Pointcut(value="execution(* *(..))")
- public void pointcut() {}
- //3 拦截器的interceptor
- @Around(value="pointcut()")
- public Object around(ProceedingJoinPoint pjp) throws Throwable {
- Object retVal=null;
- //预处理
- //前置条件判断
- boolean ok = true;
- if(!ok) {//不满足条件
- throw new RuntimeException("你没有权限");
- }
- else {//调用目标对象的某个方法
- retVal = pjp.proceed();
- }
- //后处理
- return retVal;
- }
//2 切入点
@Pointcut(value="execution(* *(..))")
public void pointcut() {}
//3 拦截器的interceptor
@Around(value="pointcut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
Object retVal=null;
//预处理
//前置条件判断
boolean ok = true;
if(!ok) {//不满足条件
throw new RuntimeException("你没有权限");
}
else {//调用目标对象的某个方法
retVal = pjp.proceed();
}
//后处理
return retVal;
}

·代码纠结/混乱——当一个模块或代码段同时管理多个关注点时发生这种情况。如我既要实现业务、还要实现安全和事务。即有些关注点同时被多个不同的模块实现。实现了重复的功能。
·代码分散——当一个关注点分布在许多模块中并且未能很好地局部化和模块化时发生这种情况 。如许多模块调用用户是否登录验证代码。调用了重复的功能。
SpringAOP浅析的更多相关文章
- SQL Server on Linux 理由浅析
SQL Server on Linux 理由浅析 今天的爆炸性新闻<SQL Server on Linux>基本上在各大科技媒体上刷屏了 大家看到这个新闻都觉得非常震精,而美股,今天微软开 ...
- 【深入浅出jQuery】源码浅析--整体架构
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- 高性能IO模型浅析
高性能IO模型浅析 服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(Blocking IO):即传统的IO模型. (2)同步非阻塞IO(Non-blocking ...
- netty5 HTTP协议栈浅析与实践
一.说在前面的话 前段时间,工作上需要做一个针对视频质量的统计分析系统,各端(PC端.移动端和 WEB端)将视频质量数据放在一个 HTTP 请求中上报到服务器,服务器对数据进行解析.分拣后从不同的 ...
- Jvm 内存浅析 及 GC个人学习总结
从诞生至今,20多年过去,Java至今仍是使用最为广泛的语言.这仰赖于Java提供的各种技术和特性,让开发人员能优雅的编写高效的程序.今天我们就来说说Java的一项基本但非常重要的技术内存管理 了解C ...
- 从源码浅析MVC的MvcRouteHandler、MvcHandler和MvcHttpHandler
熟悉WebForm开发的朋友一定都知道,Page类必须实现一个接口,就是IHttpHandler.HttpHandler是一个HTTP请求的真正处理中心,在HttpHandler容器中,ASP.NET ...
- 【深入浅出jQuery】源码浅析2--奇技淫巧
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- 浅析匿名函数、lambda表达式、闭包(closure)区别与作用
浅析匿名函数.lambda表达式.闭包(closure)区别与作用 所有的主流编程语言都对函数式编程有支持,比如c++11.python和java中有lambda表达式.lua和JavaScript中 ...
- word-break|overflow-wrap|word-wrap——CSS英文断句浅析
---恢复内容开始--- word-break|overflow-wrap|word-wrap--CSS英文断句浅析 一 问题引入 今天在再次学习 overflow 属性的时候,查看效果时,看到如下结 ...
随机推荐
- SpringBoot目录文件结构总结(5)
1.目录 src/main/java :存放java代码 src/main/resources static:存放静态文件,比如css.js.image(访问方式 http://localhost:8 ...
- robot_framewok自动化测试--(2)创建第一个项目
创建第一个robot_framewok项目 通过 RIDE 去学习和使用 Robot Framework 框架,对于初学者来说大大的降低了学习难度.所以后面对 Robot Framework 框架都将 ...
- python-文件操作(一)
目录 文件操作 1.什么是文件? 2.操作文件的方法: 3.路径分类: 4.如何取消特殊字符的功能: 5.对文件的操作有:读.写.追加内容 6.with上下文管理 7.文件操作方法详细: 1.r-读操 ...
- Python 练习 进程
... """ 创建2个进程, 每一个进程都打出当前的时间和进程的标识,持续打十次. """ import multiprocessing ...
- NOIP2021游记(退役记)
11月 13日 停课了 学了一上午+一晚上的分块. 下午月赛切掉两道题之后xzh发现E题是道树剖,果断开始切E. 结果: 做了快两个小时还是0分. 11月 14日 上午把黄题冲上了100,绿题冲上了5 ...
- [spojSUBLEX]Lexicographical Substring Search
建立后缀自动机,对于同一个节点,出现次数是相同的(right的大小),同时满足单调性(长度越长出现次数越少),所以只需要考虑最长的串即可. PS:似乎也并不需要求依次后缀的max,不知道为什么-- 1 ...
- OAuth 2.1 带来了哪些变化
OAuth 2.1 是 OAuth 2.0 的下一个版本, OAuth 2.1 根据最佳安全实践(BCP), 目前是第18个版本,对 OAuth 2.0 协议进行整合和精简, 移除不安全的授权流程, ...
- 【低门槛 手把手】python 装饰器(Decorators)原理说明
本文目的是由浅入深地介绍python装饰器原理 装饰器(Decorators)是 Python 的一个重要部分 其功能是,在不修改原函数(类)定义代码的情况下,增加新的功能 为了理解和实现装饰器,我们 ...
- OpenFOAM 中 c++ 基础
文件布置 在 OpenFOAM 中,所有代码都以注释段开头,使用有限体积的 CFD 类型文件都包括以下头文件 #include "fvCFD.H" 在此头文件种,仅包含类或函数的定 ...
- python版的MCScan绘图
最近发现了python版的MCScan,是个大宝藏.由于走了不少弯路,终于画出美图,赶紧记录下来. github地址 https://github.com/tanghaibao/jcvi/wiki/M ...