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 属性的时候,查看效果时,看到如下结 ...
随机推荐
- 一款吊炸天的AI图片增强工具!
背景 如果你工作中需要制作文档,PPT,或者给文章配图,或者需要制作视频.一定会有在网上寻找图片素材的经历. 但网上的图质量参差不一,有时候找到了喜欢的图,但是质量不行,分辨率太低. 有的人就忍了,但 ...
- requests之代理的使用
import requests # 访问url url = 'http://www.baidu.com/s?' # 请求头 headers = { 'User-Agent': 'Mozilla/5.0 ...
- python3下tomorow模块 @thread报语法错误def async(n, base_type, timeout=None): ^ SyntaxError: invalid syntax---解决方法
遇见问题:python使用tomorrow实现多线程,tomorrow模块的源代码报语法错误? 这是报错信息:Traceback (most recent call last): File &quo ...
- liunx基础知识点1:系统管理相关命令、目录操作命令、文本编辑、关闭防火墙、重启和关闭
Linux(一) liunx系统那么重要,作为一个测试人员,不掌握你就损失了好几千,为了这个钱,也为了面子,什么鬼?我爱膨胀.你看看这些知识喽.我整理的,可费工夫了. 下次给大家一个面试题啊,更直观
- 18.jvm调优工具及案例分析
目标: Jmap.Jstack.Jinfo详解 JvisualVm调优工具实战 JVM内存或CPU飙高如何定位 JState命令预估JVM运行情况 系统频繁Full GC导致系统卡顿实战调优 内存泄漏 ...
- python中整除后结果也是小数
有人这么回答,这显然不对 先看个例子: '//'明明是整除,为什么结果不是整数,而会出现小数? 首先,关于除法有三种概念:传统除法.精确除法和地板除 #1.传统除法:整数相除结果是整数,浮点数相除结果 ...
- [atARC096F]Sweet Alchemy
给定一棵有根树,记$f_{i}$表示$i$的父亲,每一个点有一个代价$c_{i}$ 给定常数$D$和$X$,再给每个点赋一个权值$v_{i}$($v_{i}\ge 0$),满足以下条件下最大化$\su ...
- [bzoj3038]上帝造题的7分钟2
考虑每一个位置最多开6次左右就会变成1,然后操作就没有意义了,因此对线段树维护区间和和一个标记,表示是否全部都是1,然后对于修改,如果区间标记不是1就暴力下去,是1就不用操作,复杂度为$o(6nlog ...
- 回顾Servlet开发
1.建立的文件 2.servlet package com.shao.servlet; import javax.servlet.ServletException; import javax.serv ...
- Python之阶乘代码
#coding=utf-8 while True: num = int(input("请输入要阶乘的正整数数字,按负数退出:")) jiec=1 if nu ...