在上一章我们看到了,新增的三种类都能实现对原始功能类进行添加功能的事务处理,这三种类就是一个代理。

但是这种代理是写死的,怎样实现对任意接口添加自定义的代理呢?

我们先来看一下之前的代理实现:

 public class Impeat {
private InterfaceDo todo;
public Impeat(InterfaceDo todo) {
super();
this.todo = todo;
}
public void dothings() {
todo.dosomething();
System.out.println("我要吃饭了啊--------");
}
}

因为这里我们的代理不需要再被其他代理引用,所以就不需要实现InterfaceDo接口,自然内部方法也是可以自定义,没有必要

遵循InterfaceDo的方法定义,为了避免混淆,我们将其改为了dothings(),由于代理类都是这样的一个书写模式:定义成员变量、

构造函数为成员变量赋值为代理对象、自定义方法实现对代理对象方法的调用。我们索性定义一个接口,以后所有的代理类都按

照统一模式来写,在JDK中就定义了这样的一个接口InvocationHandler,我们的代理类都实现这个接口,遵循它的书写方式,

下面我们再来看看代理类里面的元素:

InterfaceDo:需要代理对象的实现接口;

todo:需要代理的对象;

红字:为代理对象添加的功能实现;

todo.dosomething():代理对象的原始功能。

既然要实现动态代理,那么这个代理实现的部分源码,就不能写死了(被代理对象的接口、被代理的对象以及被代理对象内部的

方法),接口我们可以自定义,被代理对象我们可以new出来,但是被代理对象内部的方法是不确定的,A代理对象可能是A方法,

B代理对象可能是B方法,C代理对象可能是C方法。

所以,我们要动态获取代理对象的内部方法就得通过反射来获得。

被代理对象的方法怎么获得呢?由于被代理对象是实现了接口的,被代理对象的内部方法必定也是重写自接口的定义方法的。那么

我们就可以从接口入手,获取接口的方法定义。

来看看JDK的实现:

public class Handlerimp implements InvocationHandler {
private Object obj;
public Handlerimp(Object obj) {
super();
this.obj = obj;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("-----我要实现新的功能-----");
Object returnValue = method.invoke(obj, args);
return returnValue;
}
}

是不是很眼熟,对,这个和我们之前的静态代理实现模式一样。只不过底层已经用反射帮我们获得了被代理对象obj的方法method

以及方法的参数数组,然后通过被代理对象、方法、参数三者来执行被代理对象的方法-------method.invoke(proxy,args)。

接下来,我们实例化一个该代理类的实例:

public class Testperson {
public static void main(String[] args) {
InterfaceDo a = new Persontodo();
Handlerimp handler =new Handlerimp(a);
ClassLoader loader = a.getClass().getClassLoader();
Class[] interfaces = a.getClass().getInterfaces();
InterfaceDo subject = (InterfaceDo) Proxy.newProxyInstance(loader, interfaces, handler);
subject.dosomething();
subject.dothing();
}
}

我们可以看到,JDK中通过Proxy类的静态方法newProxyInstance()获得代理类实例;

该方法实现了对被代理对象所有方法的遍历,因此实现了对被代理对象所有方法的功能添加。

之后,我们就可以调用代理类的方法了。

java之Spring(AOP)前奏-动态代理设计模式(下)的更多相关文章

  1. Spring AOP 前奏--动态代理

  2. Spring AOP 和 动态代理技术

    AOP 是什么东西 首先来说 AOP 并不是 Spring 框架的核心技术之一,AOP 全称 Aspect Orient Programming,即面向切面的编程.其要解决的问题就是在不改变源代码的情 ...

  3. Spring AOP --JDK动态代理方式

    我们知道Spring是通过JDK或者CGLib实现动态代理的,今天我们讨论一下JDK实现动态代理的原理. 一.简述 Spring在解析Bean的定义之后会将Bean的定义生成一个BeanDefinit ...

  4. Spring AOP之动态代理

    软件151 李飞瑶 一.Spring 动态代理中的基本概念  1.关注点(concern)    一个关注点可以是一个特定的问题,概念.或者应用程序的兴趣点.总而言之,应用程序必须达到一个目标    ...

  5. Spring AOP JDK动态代理与CGLib动态代理区别

    静态代理与动态代理 静态代理 代理模式 (1)代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. (2)静态代理由 业务实现类.业务代理类 两部分 ...

  6. java之Spring(AOP)前奏-动态代理设计模式(上)

    我们常常会遇到这样的事,项目经理让你为一个功能类再加一个功能A,然后你加班为这个类加上了功能A: 过了两天又来了新需求,再在A功能后面加上一个新功能B,你加班写好了这个功能B,加在了A后面:又过 了几 ...

  7. Java编程的逻辑 (86) - 动态代理

    ​本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...

  8. 浅谈Spring中JDK动态代理与CGLIB动态代理

    前言Spring是Java程序员基本不可能绕开的一个框架,它的核心思想是IOC(控制反转)和AOP(面向切面编程).在Spring中这两个核心思想都是基于设计模式实现的,IOC思想的实现基于工厂模式, ...

  9. AOP jdk动态代理

    一: jdk动态代理是Spring AOP默认的代理方法.要求 被代理类要实现接口,只有接口里的方法才能被代理,主要步骤是先创建接口,接口里创建要被代理的方法,然后定义一个实现类实现该接口,接着将被代 ...

随机推荐

  1. C#弹出对话框

    一.基于WINFORM下的选择对话框 在WINFORM下,我们可以利用系统的对话框(MessageBox)来实现,具体思路是读取MessageBox的返回值(YES或NO)来达到对操作的控制.下面是一 ...

  2. oracle ORA-00917: missing comma 是因为少逗号

    oracle ORA-00917: missing comma 是因为少逗号,而且不是网上盛传的空格问题!都是传言误人啊

  3. AngularJS进阶(三十八)上拉加载问题解决方法

    AngularJS上拉加载问题解决方法 项目中始终存在一个问题:当在搜索栏输入关键词后(见图1),按照既定的业务逻辑应该是服务端接收到请求后,首先返回查询的前7条数据,待客户端出现上拉加载时,继续查找 ...

  4. MacTalk·人生元编程 - 读书笔记

    简介 <MacTalk·人生元编程>是一本随笔文集,主要内容来自作者的微信公众平台"MacTalk By 池建强".本书撰写于2013年,书中时间线却不止于此.作者以一 ...

  5. FSG报表打印报错,log文件显示java.sql.SQLException: No corresponding LOB data found

    报错信息: +---------------------------------------------------------------------------+ Plsql 程序的日志信息开始 ...

  6. 中国梦&nbsp;&nbsp;每个农大人的梦

    历经百年风霜,苦经岁月沧桑.农大,一个中原沃土上生长起来的大树,它在用它那不倒的生命力展示着农大的顽强与坚持,而这份苍劲和顽强,却来自于每个农大人,来自于他们的梦想,来自于他们的坚持,来自于他们的努力 ...

  7. JQuery实战总结二 横向纵向菜单下拉效果图

    记得以前在浏览了大多数网站的上面发现很多下拉的导航栏,觉得特别好玩,毕竟咱们是学习编程的嘛,对这下拉的效果还是挺感兴趣的,这种淡入淡出,随着鼠标移动的位置不同.有无等而出现不同的效果,给用户以神美感. ...

  8. linux内核代码的编写初步以及makefile的配置

    在linux内核代码开发中,头文件不能包含标准C头文件,只能采用GNC标准 而且内核开发中没有main函数,只有init 和 exit ,这是每个内核模块中必须要包含的函数模块. 在GNU C标准中, ...

  9. 基于ROS_Arduino室内移动机器人SLAM实验测试

    纯手工搭建的机器人,因此外观并不美. 基于ROS(indigo)以及Arduino等搭建软硬件平台,包括语音.视觉.激光.码盘等传感器设备. 整体如下图所示: 底盘特写: 语音输入: Arduino模 ...

  10. Retinex图像增强算法

    前一段时间研究了一下图像增强算法,发现Retinex理论在彩色图像增强.图像去雾.彩色图像恢复方面拥有很好的效果,下面介绍一下我对该算法的理解. Retinex理论 Retinex理论始于Land和M ...