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 ...
随机推荐
- 网站压力测试ab 命令
网站压力测试ab 命令 author: headsen chen 2017-10-25 10:06:35 个人原创,转载请注明作者,出处,否则依法追究法律责任! 1,制作一个a ...
- Asp.Net Core 2.0 项目实战(10) 基于cookie登录授权认证并实现前台会员、后台管理员同时登录
1.登录的实现 登录功能实现起来有哪些常用的方式,大家首先想到的肯定是cookie或session或cookie+session,当然还有其他模式,今天主要探讨一下在Asp.net core 2.0下 ...
- 获取DOM节点的几种方式
DOM 是一个树形结构,操作一个DOM节点,实际上就是这几个操作:更新.删除.添加.遍历 在操作DOM节点之前,需要通过各种方式先拿到这个DOM节点,常用的方法有: 一.通过元素类型的方法来操作: d ...
- Kafka OffsetMonitor:监控消费者和延迟的队列
一个小应用程序来监视kafka消费者的进度和它们的延迟的队列. KafkaOffsetMonitor是用来实时监控Kafka集群中的consumer以及在队列中的位置(偏移量). 你可以查看当前的消费 ...
- DB2开发系列之三——SQL函数
1.内置函数分类(SYSIBM模式内) 1)标量函数:返回一个标量值的函数: 2)聚合函数:也叫列函数,也返回一个标量值,这个值是一组输入值的计算结果:3)表函数:向引用它的 SQL 语句返回一个表: ...
- 使用MVC5+Entity Framework6的Code First模式创建数据库并实现增删改查功能
此处采用VS2017+SqlServer数据库 一.创建项目并引用dll: 1.创建一个MVC项目 2.采用Nuget安装EF6.1.3 二.创建Model 在models文件夹中,建立相应的mode ...
- Welcome to StackEdit!
Welcome to StackEdit! Hey!our first Markdown document in StackEdit1. Don't delete me, I'm very helpf ...
- C语言第二次博客作业---分支结构 陈张鑫
一.PTA实验作业 题目1:计算分段函数[2] 本题目要求计算下列分段函数f(x)的值: 1.实验代码 int main(){double x,y; scanf("%lf",&am ...
- C语言的第0次作业
你认为大学的学习生活.同学关系.师生关系应该是怎样? 1.我觉得大学生活应该充实而富有意义,不荒废学业,合理分配时间,让自己有一技之长,与时代接轨. 2.同学之间应该顺其自然的相处,不做作,不矫情,真 ...
- Python打包分发工具setuptools
作为Python标准的打包及分发工具,setuptools可以说相当地简单易用.它会随着Python一起安装在你的机器上.你只需写一个简短的setup.py安装文件,就可以将你的Python应用打包 ...