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的实现原理(动态代理)的更多相关文章

  1. AOP的实现原理——动态代理

    IOC负责将对象动态的 注入到容器,从而达到一种需要谁就注入谁,什么时候需要就什么时候注入的效果,可谓是招之则来,挥之则去.想想都觉得爽,如果现实生活中也有这本事那就爽 歪歪了,至于有多爽,各位自己脑 ...

  2. 菜鸟学SSH(十四)——Spring容器AOP的实现原理——动态代理

    之前写了一篇关于IOC的博客——<Spring容器IOC解析及简单实现>,今天再来聊聊AOP.大家都知道Spring的两大特性是IOC和AOP,换句话说,容器的两大特性就是IOC和AOP. ...

  3. 浅析Spring中AOP的实现原理——动态代理

    一.前言   最近在复习Spring的相关内容,刚刚大致研究了一下Spring中,AOP的实现原理.这篇博客就来简单地聊一聊Spring的AOP是如何实现的,并通过一个简单的测试用例来验证一下.废话不 ...

  4. Spring 容器AOP的实现原理——动态代理

    参考:http://wiki.jikexueyuan.com/project/ssh-noob-learning/dynamic-proxy.html(from极客学院) 一.介绍 Spring的动态 ...

  5. Spring容器AOP的实现原理——动态代理(转)

    文章转自http://blog.csdn.net/liushuijinger/article/details/37829049#comments

  6. Hibernate学习--hibernate延迟加载原理-动态代理(阿里电面)

    在正式说hibernate延迟加载时,先说说一个比较奇怪的现象吧:hibernate中,在many-to-one时,如果我们设置了延迟加载,会发现我们在eclipse的调试框中查看one对应对象时,它 ...

  7. 新秀学习SSH(十四)——Spring集装箱AOP其原理——动态代理

    之前写了一篇文章IOC该博客--<Spring容器IOC解析及简单实现>,今天再来聊聊AOP.大家都知道Spring的两大特性是IOC和AOP. IOC负责将对象动态的注入到容器,从而达到 ...

  8. Spring AOP实现原理-动态代理

    目录 代理模式 静态代理 动态代理 代理模式 我们知道,Spring AOP的主要作用就是不通过修改源代码的方式.将非核心功能代码织入来实现对方法的增强.那么Spring AOP的底层如何实现对方法的 ...

  9. 二)Spring AOP编程思想与动态代理

    一.aop编程思想 1.面向切面,就是能够不动源码的情况下,从横切面切入新的代码功能. 2.实现原理是动态代理 动态代理的步骤 a.写生产厂家,实现接口,代理只能代理接口 b.动态代理类实现Invoc ...

随机推荐

  1. CentOS 远程桌面相关服务安装笔记

    # CentOS 7安装图形界面 sudo yum groupinstall "GNOME Desktop" "Graphical Administration Tool ...

  2. New Windows 10 SDK - Toast Notification

    概述 Toast Notification 在 UWP App 中有很重要的作用,能够很大程度上增强 App 和用户之间的沟通,比如运营推广活动.版本更新.提醒类任务提示等等.Toast Notifi ...

  3. 强大核心功能矩阵,详解腾讯云负载均衡CLB高可靠高性能背后架构

    1 前言 腾讯云负载均衡(Cloud LoadBalancer),简称CLB, 负载均衡通过设置虚拟服务地址(VIP)将来自客户端的请求按照指定方式分发到其关联的多台后端云服务器,服务器将请求的响应返 ...

  4. Java内存区域之程序计数器--《深入理解Java虚拟机》学习笔记及个人理解(一)

    Java虚拟机程序计数器 在书上的P39页 程序计数器干嘛的? 有了它,字节码解释器才可以知道下一条要执行的字节码指令是哪个. 无论是取下一条指令还是分支.循环.跳转.中断.线程恢复,都需要这个程序计 ...

  5. business expressions(一)

    一. 1.24/7 24/7 :twenty four hours a day, seven days a week I work 24/7.——meaing i work all the time. ...

  6. Post Office

    Post Office poj-1160 题目大意:给你在数轴上的n个村庄,建立m个邮局,使得每一个村庄距离它最近的邮局的距离和最小,求距离最小和. 注释:n<=300,m<=min(n, ...

  7. linux特殊字符及其作用

    1.通配符    ? 匹配单个字符    * 代表所有字符     [abcd] 匹配[]里任意一个字符.4选1 [a-d]    [!abcd]  匹配不含[]里任意一个字符的字符.[^abcd] ...

  8. CodeBlocks使用介绍

    CodeBlocks对单个文件没法调试,需要建工程后才能调试,所以使用CodeBlocks必须先建工程. 一.如何用CodeBlocks建工程文件. 选择File->New->Projec ...

  9. Beta 凡事预则立

    写在Beta冲刺前 关于组长是否重选的议题和结论 总体结论 组长无需更换 队内无人替代 理由 当前组长能够较好的号召和组织团队成员进行工作 当前组长能够对项目有合理的规划 当前组长被大家一致认可可以继 ...

  10. 201621123050 《Java程序设计》第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1. 源代码阅读:多线程程序BounceThread 1.1 BallR ...