【Java】代理模式、反射机制-动态代理
关于代理模式和动态代理参考自:https://www.cnblogs.com/gonjan-blog/p/6685611.html
这里通过参考博客中的例子整理个人理解。
代理模式:
访问某个类的方法由直接调用方法,变为通过中间人练习。
即调用方➡功能提供者,变更为调用方➡代理人➡功能提供者。
这样做的好处:
1.调用方不再关注功能提供者的具体行为,专为代理人统一关注,调用方只用关注代理人的行为(接口)。
2.代理人可以在真正调用功能提供者的方法前后进行再加工提供部分行为。
静态代理:
在编译阶段已经知道代理人、功能提供者、调用方的关系。
动态代理:
代理人在编译阶段不知道调用方和功能提供者的类型,在运行时通过传入的参数动态建立代理关系。
因此动态代理的加工行为可以对拥有被代理人临时生效,比如计算任何功能提供者执行方法的时间。。
以下是例子:
静态代理:
Person接口代表所有学生,所有学生都有交班费的行为
package com.xdsux.java.proxy;
public interface Person {
//静态代理与功能提供者的统一接口
void giveMoney();
}
Student实现了Person接口的交班费行为:
package com.xdsux.java.proxy;
public class Student implements Person {
@Override
public void giveMoney() {
System.out.println("学生提交班费:50");
}
}
Monitor即代理(班长),班长可以找任何学生提交班费:
package com.xdsux.java.proxy;
public class Monitor implements Person {
//班长即代理,持有学生实例
Student stu;
public Monitor(Person stu) {
this.stu = (Student)stu;
}
@Override
public void giveMoney() {
//班长叫学生交班费
stu.giveMoney();
}
}
测试,也就是老师叫班长去收班费:
package com.xdsux.java.proxy;
public class TestProxy {
public static void main(String[] args) {
//某学生
Student stu = new Student();
//某班长
Monitor mon = new Monitor(stu);
mon.giveMoney();
}
}
1.班长可以向任何一个学生收班费,在收取班费时可以加入其他动作,比如查询学生上次是否未交。
2.班长可以采用单例模式(一个班只有一个班长)
3.学生的缴费行为可以变动(学生出现子类贫困生,可能不需要交班费),但老师不必关心,班长负责和学生重新确定缴费行为,老师可以依然调用mon.giveMoney
动态代理
代理类需要实现InvovationHabdler接口:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; public class StuInvocationHandler<T> implements InvocationHandler { // 事先不知道代理谁
T target; public StuInvocationHandler(T target) {
this.target = target;
} /**
* proxy:代理动态对象 method:代表需要执行的方法 args:调用目标方法时要传入的参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理执行" + method.getName() + "方法");
// 代理过程中插入监测方法,计算该方法耗时
MonitorUtil.start();
Object result = method.invoke(target, args);
MonitorUtil.finish(method.getName());
return result;
} }
代理会根据传入的实例和参数执行方法,并在每次代理时,计算目标方法的执行时间:
package com.xdsux.java.proxy; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy; public class TestProxy {
public static void main(String[] args) {
//某学生
Student stu = new Student(); //创建一个与代理对象相关联的InvocationHandler
InvocationHandler stuHandler = new StuInvocationHandler<Person>(stu); //创建一个代理对象stuProxy来代理某学生,代理对象的每个执行方法都会替换执行Invocation中的invoke方法
Person stuProxy = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class<?>[]{Person.class}, stuHandler);
//代理执行上交班费的方法
stuProxy.giveMoney();
}
}
【Java】代理模式、反射机制-动态代理的更多相关文章
- Java反射机制动态代理
1.什么事反射机制动态代理 在一段代码的前后动态执行其他操作,比如有一个方法是往数据库添加一个记录,我们可以通过动态代理,在操作数据库方法的前和后添加代码执行打开数据库连接和关闭数据库连接. 2.演示 ...
- Spring代理模式(jdk动态代理模式)
有动态代理和静态代理: 静态代理就是普通的Java继承调用方法. Spring有俩种动态代理模式:jdk动态代理模式 和 CGLIB动态代理 jdk动态代理模式: 代码实现: 房东出租房子的方法(继承 ...
- Java高级特性—反射和动态代理
1).反射 通过反射的方式可以获取class对象中的属性.方法.构造函数等,一下是实例: 2).动态代理 使用场景: 在之前的代码调用阶段,我们用action调用service的方法实现业务即可. 由 ...
- 代理模式之cglib动态代理
上一篇博客说了实现InvocationHandler接口的jdk动态代理,还有一种实现动态代理的方式则是:通过继承的方式实现的cglib动态代理. 先在程序中导入cglib的包,cglib-nodep ...
- 代理模式及jdk动态代理原理
代理模式 :为其它对象提供代理,以控制对这个对象的访问. 代理模式的特征:代理类(proxyClass)与委托类(realClass)有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转 ...
- Java基础之反射和动态代理
1,反射是依赖于Class对象,然后根据Class对象,去操作该类的资源的.Class对象是发射的基石! 问题1:人这类事物用什么表示?汽车这类事物用什么表示>计算机文件用什么表示?有如此多的事 ...
- java 27 - 9 反射之 动态代理的概述和实现
代理:本来应该自己做的事情,却请了别人来做,被请的人就是代理对象. 举例:春季回家买票让人代买 动态代理: 在程序运行过程中产生的这个对象 而程序运行过程中产生对象其实就是我们刚才反射讲解的内容,所以 ...
- java 代理模式二:动态代理
java动态代理: java动态代理类位于java.lang.reflect包下,一般主要涉及两个类: 1.Interface InvocationHandler 该接口中仅定义了一个方法:Objec ...
- java 27 - 10 反射之 动态代理的代码实现
为什么要写动态代理类? 例子: 如果现在想做个登陆注册的功能.用户可以执行登陆.注册.添加.删除这些功能. 但是,有些功能是要有一定权限才可以执行的. 而现在已经有了个用户类的接口和该类的实现类了,但 ...
随机推荐
- 【剑指offer】链表第一个公共子结点
*思路: 先求得两个链表的长度,然后得到长度差diff,再先遍历长链表diff步后,再同时遍历两个链表并比较对象指针. /* public class ListNode { int val; List ...
- CSS之display
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- HTML/CSS基础知识(三)
浏览器内核 浏览器内核是浏览器的核心,也称“渲染引擎”,用来解释网页语法并渲染到网页上.浏览器内核决定了浏览器该如何显示网页内容以及页面的格式信息.不同的浏览器内核对网页的语法解释也不同,因此网页开发 ...
- javascript常用工具类整理(copy)
JavaScript常用工具类 类型 日期 数组 字符串 数字 网络请求 节点 存储 其他 1.类型 isString (o) { //是否字符串 return Object.prototype.to ...
- k8s学习笔记之五:Pod资源清单spec字段常用字段及含义
第一章.前言 在上一篇博客中,我们大致简述了一般情况下资源清单的格式,以及如何获得清单配置的命令帮助,下面我们再讲解下清单中spec字段中比较常见的字段及其含义 第二章.常用字段讲解 spec.con ...
- 性能测试Jmeter扩展学习-添加自定义函数
我们在使用jmeter的时候有时候会碰到jmeter现有插件或功能也无法支持的场景,比如前端加密,此时我们就需要自己手动编写函数并导入了,下面就是手动修改并导入的过程. 首先我们需要下载jmeter源 ...
- 61.纯 CSS 创作一只咖啡壶(这个不好看)
原文地址:https://segmentfault.com/a/1190000015376202 感想: 好像不像呀,啊啊啊.伪元素.定位.动画.width和height包括内边距|边框|内容区. H ...
- JDK1.7 高并发下的HashMap
HashMap的容量是有限的.当经过多次元素插入,使得HashMap达到一定饱和度时,Key映射位置发生冲突的几率会逐渐提高. 这时候,HashMap需要扩展它的长度,也就是进行Resize. 影响发 ...
- react-native-pushy 热更新
教程来源于官网: 准备工作 添加热更新功能 发布应用 说明: 在往 pushy 发布了安装包之后,后续都是通过下面 2个命令来发布 热更新版本的,而不是再次发布安装包, 在使用热更新服务更新版本的时候 ...
- python中的新式类与旧式类
在python2中,有新式类与旧式类的区别: 首先创建一个类: class Sb(object): pass 如果创建时继承自object,说明这是一个新式类,不写object,说明是一个旧式类: 那 ...