spring5——Aop的实现原理(动态代理)
spring框架的核心之一AOP,面向切面编程是一种编程思想。我对于面向切面编程的理解是:可以让我们动态的控制程序的执行流程及执行结果。spring框架对AOP的实现是为了使业务逻辑之间实现分离,分离主业务逻辑及次要业务逻辑,进而降低系统间的耦合度。
spring框架对于这种编程思想的实现基于两种动态代理模式,分别是 JDK动态代理 及 CGLIB的动态代理,这两种动态代理的区别是 JDK动态代理需要目标对象实现接口,而 CGLIB的动态代理则不需要。下面我们通过一个实例来实现动态代理,进而帮助我们理解面向切面编程。
需求:实现一个除法运算器,要求计算出两个整数相除的商,其中除数为0时提示用户"除数不能为零"并返回-1,被除数为0零时直接返回0。
我们来看一下一般的做法。
public int division(int a,int b){
if(b == 0){
System.out.println("除数不能为0");
return -1;
}else if(a == 0){
return 0;
}else{
return a/b;
}
}
我们来分析一下需求,“计算出两个整数相除的商”是我们的主业务逻辑,而“除数为0时提示用户"除数不能为零"并返回-1,被除数为0零时直接返回0”是我们的次要业务逻辑,以上的做法无疑是吧,主业务逻辑和次要业务逻辑偶合到了一块。这里只是做了一个除法,可当你的主业务逻辑本身就就比价复杂的,再这样做的话就会增加代码的偶合度及可读性。
下面我们使用 JDK的 动态代理来实现以上的需求,虽然以下的做法看起来像是杀鸡用牛刀,但我们这里只是为了说明问题。
JDK的动态代理要使用到一个类 Proxy 用于创建动态代理的对象,一个接口 InvocationHandler用于监听代理对象的行为,其实动态代理的本质就是对代理对象行为的监听。
首先我们需要提供一个主业务逻辑的接口,这 JDK动态代理实现的先决条件。
public interface IDivisionService {
int division(int a ,int b);
}
下面是实现类(实现类中只有主页业务逻辑)
public class DivisionServiceImpl implements IDivisionService {
@Override
public int division(int a, int b) {
return a/b;
}
}
下面我们来看一下动态代理是怎么分离主业务逻辑和次要业务逻辑的。
首先准备一个创建代理对象的工厂类
public class BeanFactory {
public static Object getAgencyObj(final Object target){
Object agencyObj = null;
agencyObj = Proxy.newProxyInstance(
//获取目标对象类的加载器
target.getClass().getClassLoader(),
//获取对象接口的Class对象数组
target.getClass().getInterfaces(),
//一个内部类,用于创建监听对象
new InvocationHandler() {
/**
* 通过反射机制获得实现类中方法的实例 method 及方法的参数 args 这取决于代理对象 agencyObj调用了那个方法。
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
int a = (int)args[0];
int b = (int)args[1];
//用于处理次要业务逻辑
if(b == 0){
System.out.println("除数不能为0");
return -1;
}
//用于处理次要业务逻辑
if(a == 0){
return 0;
}
//执行主业务逻辑
Object result = method.invoke(target, args);
return result;
}
});
return agencyObj;
}
}
最后测试类:
public class MyTest {
public static void main(String[] args) {
//创建目标类
IDivisionService target = new DivisionServiceImpl();
//创建代理对象
IDivisionService agencyObj = (IDivisionService)BeanFactory.getAgencyObj(target);
int consult = agencyObj.division(0, 2);
System.out.println("两数相除商为--->"+consult);
}
}
在这里我们看到,除法计算器的实现类DivisionServiceImpl 只是来做除法这一主业务逻辑,而 “除数为0时提示用户"除数不能为零"并返回-1,被除数为0零时直接返回0”这一次要业务逻辑交由JDK的动态代理来实现。
最后说一点,我们作为程序员,研究问题还是要仔细深入一点的。当你对原理了解的有够透彻,开发起来也就得心应手了,很多开发中的问题和疑惑也就迎刃而解了,而且在面对其他问题的时候也可做到触类旁通。当然在开发中没有太多的时间让你去研究原理,开发中要以实现功能为前提,可等项目上线的后,你有大把的时间或者空余的时间,你大可去刨根问底,深入的去研究一项技术,为觉得这对一名程序员的成长是很重要的事情。
spring5——Aop的实现原理(动态代理)的更多相关文章
- AOP的实现原理——动态代理
IOC负责将对象动态的 注入到容器,从而达到一种需要谁就注入谁,什么时候需要就什么时候注入的效果,可谓是招之则来,挥之则去.想想都觉得爽,如果现实生活中也有这本事那就爽 歪歪了,至于有多爽,各位自己脑 ...
- 菜鸟学SSH(十四)——Spring容器AOP的实现原理——动态代理
之前写了一篇关于IOC的博客——<Spring容器IOC解析及简单实现>,今天再来聊聊AOP.大家都知道Spring的两大特性是IOC和AOP,换句话说,容器的两大特性就是IOC和AOP. ...
- 浅析Spring中AOP的实现原理——动态代理
一.前言 最近在复习Spring的相关内容,刚刚大致研究了一下Spring中,AOP的实现原理.这篇博客就来简单地聊一聊Spring的AOP是如何实现的,并通过一个简单的测试用例来验证一下.废话不 ...
- Spring 容器AOP的实现原理——动态代理
参考:http://wiki.jikexueyuan.com/project/ssh-noob-learning/dynamic-proxy.html(from极客学院) 一.介绍 Spring的动态 ...
- Spring容器AOP的实现原理——动态代理(转)
文章转自http://blog.csdn.net/liushuijinger/article/details/37829049#comments
- Hibernate学习--hibernate延迟加载原理-动态代理(阿里电面)
在正式说hibernate延迟加载时,先说说一个比较奇怪的现象吧:hibernate中,在many-to-one时,如果我们设置了延迟加载,会发现我们在eclipse的调试框中查看one对应对象时,它 ...
- 新秀学习SSH(十四)——Spring集装箱AOP其原理——动态代理
之前写了一篇文章IOC该博客--<Spring容器IOC解析及简单实现>,今天再来聊聊AOP.大家都知道Spring的两大特性是IOC和AOP. IOC负责将对象动态的注入到容器,从而达到 ...
- Spring AOP实现原理-动态代理
目录 代理模式 静态代理 动态代理 代理模式 我们知道,Spring AOP的主要作用就是不通过修改源代码的方式.将非核心功能代码织入来实现对方法的增强.那么Spring AOP的底层如何实现对方法的 ...
- 二)Spring AOP编程思想与动态代理
一.aop编程思想 1.面向切面,就是能够不动源码的情况下,从横切面切入新的代码功能. 2.实现原理是动态代理 动态代理的步骤 a.写生产厂家,实现接口,代理只能代理接口 b.动态代理类实现Invoc ...
随机推荐
- hidden symbol `pthread_atfork'
gcc交叉编译时发生这种错误 /.. .../voice_demo: hidden symbol `pthread_atfork' in /opt/gcc-linaro-aarch64-linux-g ...
- delphi GDI 图片压缩代码 据说是位图缩放保持原图视觉效果最好的算法
delphi 图片压缩代码 据说是位图缩放保持原图视觉效果最好的算法 若有更好的,请大神留言我也学习下,感谢! uses WinAPI.GDIPAPI, WinAPI.GDIPOBJ; var Bi ...
- 需求分析--WBS
我们的软件天气预报的WBS如下:
- WBS
Need 需求分析: 为了满足中老年人因工作忙碌而无暇阅读的痛苦,我们设计推广出一款听书软件.可以给中老年人带来的好处是不再受繁琐的听书软件的束缚,操作简单,携带便捷. Approach 实现方法: ...
- Java String常用方法
字符串查找 两种查找字符串的方法,indexOf(String s)和lastIndexOf(String s). String str = "tyson-json"; int i ...
- ELK学习笔记(一)安装Elasticsearch、Kibana、Logstash和X-Pack
最近在学习ELK的时候踩了不少的坑,特此写个笔记记录下学习过程. 日志主要包括系统日志.应用程序日志和安全日志.系统运维和开发人员可以通过日志了解服务器软硬件信息.检查配置过程中的错误及错误发生的原因 ...
- Linux下mysql的常用操作
Linux下mysql的常用操作: 显示数据库 show databases; 选择数据库 use 数据库名; 显示数据库中的表 show tables; 显示数据表的结构 describe 表名; ...
- [Chrome 浏览器快捷键]——“你是键盘党吗?”
标签页和窗口快捷键 操作 快捷键 打开新窗口 Ctrl + n 在隐身模式下打开新窗口 Ctrl + Shift + n 打开新的标签页,并跳转到该标签页 Ctrl + t 重新打开最后关闭的标签页, ...
- [bzoj1497][NOI2006]最大获利_网络流_最小割
最大获利 bzoj-1497 题目大意:可以建立一个点,花费一定的代价:将已经建立的两个点之间连边,得到一定收益.有些节点之间是不允许连边的. 注释:1<=点数<=5,000,1<= ...
- [poj2152]fire_树形dp
fire poj-2152 题目大意:给出一颗树,给出两个相邻节点的距离,以及每个节点的接受范围,还有当前节点的代价.我们想要求出覆盖整个图的最小代价. 注释:一个点被覆盖,当且仅当该点有防火站或者这 ...