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. Keepalived+Nginx实现高可用负载均衡集群

    一 环境介绍 1.操作系统CentOS Linux release 7.2.1511 (Core) 2.服务keepalived+nginx双主高可用负载均衡集群及LAMP应用keepalived-1 ...

  2. table_rows查询优化

    日常应用运维工作中,Dev或者db本身都需要统计表的行数,以此作为应用或者维护的一个信息参考.也许很多人会忽略select count(*) from table_name类似的sql对数据库性能的影 ...

  3. java项目和java-web项目中文件和文件夹的含义

    1. java项目 .project:是工程构建配置文件 .classpath:保存的是项目所用的外部引用包的路径 .settings:记录项目配置变化的记录文件夹 src:sourcefolder项 ...

  4. 前端的UI设计与交互之数据录入篇

    数据录入是获取对象信息的重要交互方式,用户会频繁的增加.修改或删除信息.多种多样的文本录入和选择录入方式帮助用户更加清晰和高效的完成这项体验.设计者应当注意这几点:为初级用户/偶尔访问的用户提供简单易 ...

  5. Acer Aspire E1 471G 加装SSD+机械盘后无法启动的问题

    老笔记本 Acer Aspire E1 471G 加装了一块 SSD 作为系统盘(win10),原机械盘格式化后,装在光驱托架上作为数据盘. 可能会出现: 系统无法启动,显示找不到启动设备,并且在F2 ...

  6. WPF 16进制byte输入框

    在WPF中,针对byte类型的输入控件可以选用 XCEED 的免费库中的 Xceed.Wpf.Toolkit.ByteUpDown(可从nuget获取). 若要使该控件在界面上以16进制显示byte, ...

  7. 【Python】 list & dict & str

    list & dict & str 这三种类型是python中最常用的几种数据类型.他们都是序列的一种 ■ 序列通用操作 1. 分片   s[a:b] 返回序列s中从s[a]到s[b- ...

  8. 手写ButterKnife

    开发中使用注解框架可以极大地提高编码效率,注解框架用到的技术可以分为两种,运行时注解跟编译时注解.运行时注解一般配合反射机制使用,编译时注解则是用来生成模板代码.这里我们分别使用这两种方法实现Butt ...

  9. 转git取消commit

     如果不小心commit了一个不需要commit的文件,可以对其进行撤销. 先使用git log 查看 commit日志 commit 422bc088a7d6c5429f1d0760d008d8 ...

  10. C语言——第一次作业

    **学习内容总结** 本周进行了算法的初步学习,用计算机的思维方式去思考问题,并学习了如何用传统程序框图表示算法. 相关内容: 1.算法是用来解决问题的方法与步骤. 2.计算机擅长重复,常用枚举的方法 ...