-
python 动态代理模式_设计模式之动态代理模式(示例代码)
2021-01-14 07:10:46学习动态代理模式是为了以后学习AOP(面向切面编程)打下基础,他比装饰者模式还要灵活。我们只学习他的一个方法:Proxy.newProxyInstance(ClassLoader classLoader, Class[] interfaces, InvocationHandler ...学习动态代理模式是为了以后学习AOP(面向切面编程)打下基础,他比装饰者模式还要灵活。
我们只学习他的一个方法:
Proxy.newProxyInstance(ClassLoader classLoader, Class[] interfaces, InvocationHandler invocationHandler);
作用:在运行时,动态创建一组指定的接口的实现类对象。
三个参数分别是:
1. ClassLoader classLoader:类加载器
2.Class[] interfaces:指定要实现的接口
3.InvocationHandler invocationHandler:调用处理器,这是个接口
查看API得知有一个方法:
public Object invoke(Object proxy, Method method, Object[] args);
interfaceA {voida();
Object aa(String x);
}interfaceB {voidb();
}public classDemo1 {public static voidmain(String[] args) {donttai();
}private static voiddonttai() {//通过目标对象得到类加载器 Demo1 d=new Demo1();
ClassLoader classLoader = d.getClass().getClassLoader();
InvocationHandler invocationHandler= newInvocationHandler() {public Object invoke(Object proxy, Method method, Object[] args) throwsThrowable {
System.out.println("动态代理有点难");return "aaa";
}
};//使用三大参数创建代理对象
Object o =Proxy.newProxyInstance(classLoader,new Class[]{A.class, B.class}, invocationHandler);
A a=(A) o;
B b=(B) o;
a.a();
b.b();
输出:动态代理有点难
动态代理有点难
a被传递给了proxy这个参数,aa传递给了method参数,括号中的内容传递给了args1
Object aaa= a.aa("hello");
System.out.println(aaa);
输出:动态代理有点难
由此可得:代理对象实现的所有接口中的方法,内容都是调用InvocationHandler的invoke()方法
例子
public interfaceWaiter {//这个waiter可以服务别人
voidservice();
}public class ManWaiter implementsWaiter {public voidservice() {
System.out.println("服务周到");
}
}public classDemo1 {public static voidmain(String[] args) {
getOne();
}private static voidgetOne() {//manWaiter就是一个目标对象(需要被增强的)
Waiter manWaiter = newManWaiter();//通过目标对象得到类加载器
ClassLoader classLoader =manWaiter.getClass().getClassLoader();
//需要被实现的接口
Class[] interfaces= new Class[]{Waiter.class};
InvocationHandler invocationHandler= newInvocationHandler() {
@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throwsThrowable {
System.out.println("你好");
manWaiter.service();
System.out.println("再见");return null;
}
};//得到一个代理对象,代理对象就是在目标对象的基础上进行增强的对象
Waiter waiterProxy =(Waiter) Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);//在调用代理对象的时候,在前面添加“你好”,后面添加“再见”,//因为需要一个目标对象,所以需要自己传一个
waiterProxy.service();
}
}
输出:
你好
服务周到
再见
-
设计模式——代理模式(理解静态代理和动态代理+代码)
2016-11-25 11:37:45代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。 我的理解: 就这么举个例子把...代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
我的理解:
就这么举个例子把。比如我们网购。我们是直接从淘宝上买东西,而不是去实体店。淘宝这个平台就是一个代理。我们只要在网上买好东西,淘宝、快递就会帮我们送过来。
代理模式是对一个方法的加强,可以在这个方法执行的前后加上动作。比如权限的控制、日志的管理都是用到了代理模式这个原理。
(1).职责清晰真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。(2).代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介的作用和保护了目标对象的作用。(3).高扩展性
组成:抽象角色:通过接口或抽象类声明真实角色实现的业务方法。代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。静态代理:抽象角色->
package yyf.designpatterns.proxy; /** * 抽象主题,定义主要功能 */ public interface Subject { public void operate(); }
真实角色->package yyf.designpatterns.proxy; /** * 具体主题 */ public class RealSubject implements Subject { @Override public void operate() { System.out.println("real subject operate started......"); } }
代理角色->
测试->package yyf.designpatterns.proxy; import java.lang.reflect.Method; /** * 动态代理类 * * @author Yu Yufeng * */ public class ProxyHandler { private Object proxied; public ProxyHandler(Object proxied) { this.proxied = proxied; } public String invoke(Object proxy, Method method, Object[] args) throws Throwable { // 在转调具体目标对象之前,可以执行一些功能处理 System.out.println("before"); // 转调具体目标对象的方法 method.invoke(proxied, args); // 在转调具体目标对象之后,可以执行一些功能处理 System.out.println("after"); return this.toString(); } }
package yyf.designpatterns.proxy; /** * 静态代理测试 * * @author Yu Yufeng * */ public class Test { public static void main(String[] args) { Subject subject = new RealSubject(); Proxy proxy = new Proxy(subject); proxy.operate(); } } /** * 运行结果: * before operate...... * real subject operate started...... * after operate...... */
我们可以发型静态代理模式对一个类进行代理必须让真实代理类实现抽象接口。这样对代码就具有侵入性。所以,来看下动态代理。下面是一个简单的动态代理的代理类代码package yyf.designpatterns.proxy; import java.lang.reflect.Method; /** * 动态代理类 * * @author Yu Yufeng * */ public class ProxyHandler { private Object proxied; public ProxyHandler(Object proxied) { this.proxied = proxied; } public String invoke(Object proxy, Method method, Object[] args) throws Throwable { // 在转调具体目标对象之前,可以执行一些功能处理 System.out.println("before"); // 转调具体目标对象的方法 method.invoke(proxied, args); // 在转调具体目标对象之后,可以执行一些功能处理 System.out.println("after"); return this.toString(); } }
动态代理的测试类package yyf.designpatterns.proxy; /** * 动态代理测试 * * @author Yu Yufeng * */ public class Test2 { public static void main(String[] args) throws Throwable { Subject subject = new RealSubject(); ProxyHandler proxy = new ProxyHandler(subject); proxy.invoke(proxy, Subject.class.getMethod("operate"), new Object[] {}); } }
输出结果:before
real subject operate started......
after在我看来,动态代理无非就是通过反射对一个类进行加强。我们在调用真实主题的时候,就是通过反射得到了其中的方法,反射中传参数。虽然反射效率低了一点,但是这样可以做到不用修改原来的真实类,真正做到无侵入。
代码地址:https://github.com/yyfyyf1994/knowledge/tree/master/src/yyf/designpatterns/proxy
-
代理模式 静态代理 动态代理 代理模式详解
2020-11-07 10:26:18文章目录代理模式详解一、静态代理与动态代理代理模式静态代理动态代理Class Proxy二、静态代理代码实现三、动态代理代码实现 一、静态代理与动态代理 代理模式 使用一个代理对象将目标对象包装起来,凡是对这个目标...代理模式详解
一、静态代理与动态代理
代理模式
使用一个代理对象将目标对象包装起来,凡是对这个目标对象方法的调用都必须通过代理对象调用,需要被代理类与代理类实现同一个接口(有相同的方法)
静态代理
编译期间就确定好代理对象,被代理类与代理类已经固定
动态代理
运行期间通过反射动态的创建目标类的代理对象,代理类与被代理类不固定
Class Proxy
//Proxy类中的newProxyInstance方法可以创建代理对象 public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
param1:被代理类的类加载器
param2:被代理类实现的接口
param3:InvocationHandler的对象二、静态代理代码实现
//所要实现的接口 interface ClothFactory { void produceCloth(); } //被代理类 class NikeClothFactory implements ClothFactory { @Override public void produceCloth() { System.out.println("执行被代理类的方法"); } } //代理类 class ProxyClothFactory implements ClothFactory { private ClothFactory factory; //拿被代理的类对象赋值(多态) public ProxyClothFactory(ClothFactory factory) { this.factory = factory; } @Override public void produceCloth() { factory.produceCloth(); //调用被代理对象的方法 } } //测试类 public class StaticProxy { public static void main(String[] args) { //创建被代理类的对象 ClothFactory nike = new NikeClothFactory(); //创建代理类的对象 ClothFactory proxyClothFactory = new ProxyClothFactory(nike); //执行的是被代理类的方法 proxyClothFactory.produceCloth(); //执行被代理类的方法 //特点:代理类和被代理类在编译期间就确定下来了 } }
三、动态代理代码实现
//要实现的接口 interface Human { void eat(String food); } //创建不同代理类的工厂 class ProxyFactory{ /** * @param obj 被代理类的对象 * @return 动态创建的对应的代理类对象 */ public static Object getProxyInstance(Object obj) { //创建一个类实现了InvocationHandler接口,并创建此类对象 InvocationHandler handler = new MyInvocationHandler(obj); return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), handler); } } //实现InvocationHandler接口 class MyInvocationHandler implements InvocationHandler { //当代理类对象调用某个方法时,就会自动的调用如下方法 //故应当将被代理类要执行的方法声明在invoke()中 /** * @param method 被代理类要执行方法的Method类型 * @param args 被代理类要执行方法的参数 * @return 被代理类要执行方法的返回值 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object value = method.invoke(obj, args); return value; } private Object obj; //使用被代理类的对象赋值 public MyInvocationHandler(Object obj) { this.obj = obj; } } //被代理类 class SuperMan implements Human { @Override public void eat(String food) { System.out.println("我喜欢吃" + food); } } //测试类 public class ProxyTest { public static void main(String[] args) { //被代理类的对象 SuperMan superMan = new SuperMan(); //代理类的对象 Human proxyInstance = (Human)ProxyFactory.getProxyInstance(superMan); proxyInstance.eat("土豆"); //我喜欢吃土豆 } }
-
动态代理模式
2017-11-28 10:57:00动态代理能够自动监听代理对象的方法,并且能够自动生成代理类的代码,这样就不需要我们自己去重写代理对象里的方法了,这样解决了代理类代码因业务庞大而庞大的问题,因为动态代理模式会在代码运行时根据代码来在...动态代理模式简介:
动态代理能够自动监听代理对象的方法,并且能够自动生成代理类的代码,这样就不需要我们自己去重写代理对象里的方法了,这样解决了代理类代码因业务庞大而庞大的问题,因为动态代理模式会在代码运行时根据代码来在内存中动态生成一个代理类自动重写代理对象的方法,然后这个动态代理类再调用处理类里的代码,处理类再调用到实际方法上去。而且我们可以选择性的监听代理对象的方法,有些不需监听的方法就可以在处理类中过滤掉。所以动态代理的优势就在于可以自动的对代理类的方法进行统一的处理,而不用手动去修改代理类里的每个方法。
实现机制:
实现一个简单的动态代理需要四个类,第一步先编写一个接口类并声明需要的方法,第二步编写实际的实现类实现接口的方法,第三步编写ProxyHandler处理类,实现InvocationHandler接口,这个接口的方法是用来被动态代理类调用,和调用实际方法的,日志打印或者异常监控等代码语句可以写在这个方法里,最后编写测试类,测试类的main里要把实现类的对象反射出来,接着再把处理类的对象new出来,然后使用Proxy类调用生产动态带来类的方法,并且把此方法返回的对象转换成接口类型,最后使用这个接口类型的对象调用接口的方法。
在理论上可能描述的比较抽象、模糊,接下来看实际代码就清晰明了了。
第一步编写接口:
第二步编写实现类:
第三步编写处理类:
第四步编写测试类:
运行结果:
代码图解:
Debug模式执行流程:
返回:
本文转自 ZeroOne01 51CTO博客,原文链接:http://blog.51cto.com/zero01/1976633,如需转载请自行联系原作者
-
设计模式学习笔记三十四、代理模式Cglib动态代理代码实现
2020-05-20 21:43:29Cglib代理归属到动态代理。 2、Cglib代理也叫作子类代理,它是在内存中构建一个子类对象,从而实现对目标对象功能扩展。 3、Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展java类与实现java接口,它广泛... -
设计模式之动态代理的代码实现(Java)
2016-12-11 15:56:35设计模式之动态代理的代码实现(Java) -
Spring代理模式(jdk动态代理模式)
2019-09-10 22:17:24Spring有俩种动态代理模式:jdk动态代理模式 和 CGLIB动态代理 jdk动态代理模式: 代码实现: 房东出租房子的方法(继承下面出租房子的接口): package com.bjsxt.proxy1; public class FangDong ... -
设计模式-动态代理模式
2020-05-17 23:17:39摘要:代理模式有静态代理模式和动态代理模式,静态代理模式比较简单就过了,主要来看看动态代理模式以及动态代理模式在使用。 动态代理是一种增强代码功能的方式、手段,其实我们可以通过继承重写、装饰也能对代码... -
Java设计模式-代理模式之动态代理(附源代码分析)
2017-04-23 12:14:00Java设计模式-代理模式之动态代理(附源代码分析) 动态代理概念及类图 上一篇中介绍了静态代理,动态代理跟静态代理一个最大的差别就是:动态代理是在执行时刻动态的创建出代理类及其对象。... -
设计模式之代理模式、动态代理模式、Cglib代理模式
2020-11-11 11:23:57代理(Proxy)是一种设计模式,提供了对目标对象另外的访问...比如现实生活中,大多数的明细都是有经纪人 这个经纪人 就是代理 这个模式也可以称之为代理模式 代码: 先创建一个接口: public interface IStarPl... -
动态代理模式案例(代码)讲解
2020-03-28 17:37:21结果 售前服务 男性80.0 售后服务 ==================== 售前服务 女性6 售后服务 可以看到,动态代理模式符合开闭原则,无需再原来的类(代理商)上修改,只需增加新的接口及其实现类就行。 如果顾客需要新的海外... -
代理模式代码
2019-07-17 15:44:08jdk的动态代理: 需要增强的对象必须实现一个接口 package G_proxy_model; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class A_Jdk... -
利用代码分别实现jdk动态代理和cglib动态代理_代理模式解析,静态代理、动态代理一文全都告诉你...
2020-12-03 02:53:03Proxy Pattern经过两个月的学习,我们的设计模式系列学习也将近到了尾声。...这个模式想必大家都不陌生,因为 Java 程序员面试一般都会问的 Spring Aop 经过会说到动态代理,这其实就是代理模式的一... -
动态代理模式以及jdk动态代理原理
2020-12-14 16:54:42动态代理常用的有jdk的动态代理和cglib的动态代理,两者的区别是jdk动态代理是代理接口的,而cglib动态代理代理的是类。 jdk动态代理 jdk动态代理有几个重要角色: 被代理对象接口:因为jdk动态代理代理的是接口, -
动态代理模式的实现
2010-05-08 13:21:00Dynamic Proxy Pattern 动态代理模式 代码 UML2009-09-07 15:07 代理的定义:为另一个对象提供一个替身或占位符以控制对这个对象的访问。 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。在某些... -
静态动态代理模式
2020-08-30 18:43:46为什么要学习代理模式,因为AOP的底层机制就是动态代理! 代理模式: 静态代理 动态代理 静态代理 静态代理角色分析 抽象角色 : 一般使用接口或者抽象类来实现 真实角色 : 被代理的角色 代理角色 : 代理真实角色... -
设计模式之动态代理详解以及代码实现
2020-11-03 16:32:50动态代理:在内存中形成代理类 * 实现步骤: 1. 代理对象和真实对象实现相同的接口 2. 代理对象 = Proxy.newProxyInstance(); 3. 使用代理对象调用方法。 4. 增强方法 * 增强方式: -
代理模式和动态代理模式
2017-10-17 21:55:431.什么是代理模式: 代理模式:为其他对象提供一种代理以便控制对这个对象的访问。 2.抛砖 之前做过一个坦克大战的例子(好像地球人都做过哈),假定有一个接口叫moveable,坦克类Tank实现moveable接口,必须... -
java动态代理模式
2018-11-12 20:00:49我觉得动态代理模式这篇博客写的很详细了,我才明白那些多个代理Proxy的类可以通过代码去动态生成,需要什么代理做啥事情就调用invoke一次,要生成代理就生成,要某个代理去做什么事情,就把方法作为参数添加到某个... -
设计模式学习笔记三十三、代理模式JDK动态代理代码实现
2020-05-20 09:08:491、代理主要实现类 package com.hao.demo.design.dynamic; import java.lang.reflect.Proxy; /** * @author haoxiansheng * @date 2020-05-20 */ // 核心 public class ProxyFactory { // 维护一个目标对象...