Java 代理模式
来源:互联网 发布:失败 无助 知乎 编辑:程序博客网 时间:2024/06/17 03:13
写一点代理模式的个人理解
代理模式可以说是:本来由A去执行的方法,但是A不去执行,由B去代A执行。
代理可分为静态代理和动态代理,静态代理中用代理类也实现了接口的方法。动态代理中用到了反射。
先看一下静态代理的草图:
Real和代理类Proxy同时实现了接口,在客户端调用时直接调用代理类即可,然后代理类中的Real对象再去调用真正实现的方法,这样便形成了代理,达到了使用代理的目的。
优点是:代理类将真实类的方法封装了起来,可以在调用真正实现方法时添加前置和后置方法。
缺点是:实现一个代理类会多出很多的代码,造成了冗余,而且这个代理类必须事先存在。
不写这个代码了。
动态代理实现,先贴代码:
package Proxy;import java.lang.reflect.*;interface BusinessFoo{void foo();} interface BusinessBar{String bar(String message);}class BusinessFooImpl implements BusinessFoo{@Overridepublic void foo() {// TODO Auto-generated method stubSystem.out.println("BusinessFooImpl.foo()");}}class BusinessBaeImpl implements BusinessBar{@Overridepublic String bar(String message) {// TODO Auto-generated method stubSystem.out.println("BusinessBarImpl.bar()");return message;}}class BusinessImplProxy implements InvocationHandler{private Object obj; //obj是真正实现方法的对象BusinessImplProxy(){}BusinessImplProxy(Object obj){this.obj = obj;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {// TODO Auto-generated method stubObject result = null;doBefore();result = method.invoke(obj, args); //去调用真正的方法 foo()和bar()doAfter();return result;}public void doBefore() {System.out.println("Do something before Business logic");}public void doAfter() {System.out.println("Do something after Business logic");}public static Object factory(Object obj){Class<?> cls = obj.getClass(); System.out.println("cls.getClass is:"+cls.getClass());System.out.println("obj的类型是:"+obj.getClass().getName());Class<?>[] interfaces = cls.getInterfaces();for(Class<?> itf : interfaces){System.out.println(itf.getName());}System.out.println("ClassLoader is: "+cls.getClassLoader()); //ClassLoader is: sun.misc.Launcher$AppClassLoader@1372a1areturn Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), new BusinessImplProxy(obj)); //返回一个代理对象 getClassLoader()表示该运行时类 //的加载,getInterfaces()是得到运行时类的实现接口,动态代理只是实现了接口,没有实现抽象类,new BusinessImplProxy(obj)则表示真正对///象}}public class DymnaticProxy {public static void main(String[] args) {// TODO Auto-generated method stubBusinessFooImpl bFooImpl = new BusinessFooImpl();BusinessFoo bf = (BusinessFoo)BusinessImplProxy.factory(bFooImpl); bf.foo(); //去调用invoke();这一块调用哪个真正的方法,invoke中则去调用哪个System.out.println();BusinessBaeImpl bbar = new BusinessBaeImpl();BusinessBar bb = (BusinessBar)BusinessImplProxy.factory(bbar);String messageString = bb.bar("Hello world"); //去调用invoke();System.out.println(messageString);}}
代理类必须得实现InvocationHandle的接口,该接口中有一个invoke方法。
newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)方法由程序员来指定参数动态返回需要的代理类,而invoke(Object proxy,Method method, Object[] args) 方法则是由JVM在运行时动态调用的。当执行“bb.bar("Hello,World");”方法时,JVM动态指派“调用处理器”,向外层invoke传递参数,并调用method.invoke(obj,args)真正执行!
BusinessImplProxy.Factory静态方法用来动态生成代理类(“代理角色”),在运行时根据不同的业务逻辑接口BusinessFoo和BusinessBar,在运行时分别动态生成了代理角色。“抽象角色”、“代理角色”以及调用处理器(实现InvocationHandler接口的类)这三者都可以改变,所以说JAVA的动态代理十分强大。
在动态代理使用过程中有几个重要的类:Proxy,Method,Class<?>. 还有这个InvocationHandler接口。
Proxy类只能从子类为InvocationHandler构造一个Proxy实例,Proxy类的无参构造函数为私有,禁止实例化。
/** * the invocation handler for this proxy instance. * @serial */ protected InvocationHandler h; /** * Prohibits instantiation. */ private Proxy() { } /** * Constructs a new <code>Proxy</code> instance from a subclass * (typically, a dynamic proxy class) with the specified value * for its invocation handler. * * @param h the invocation handler for this proxy instance */ protected Proxy(InvocationHandler h) {this.h = h; }
<span style="font-size:14px;"></span>
public static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces)throws IllegalArgumentException
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)throws IllegalArgumentException {if (h == null) { throw new NullPointerException();}/* * Look up or generate the designated proxy class. */Class cl = getProxyClass(loader, interfaces);/* * Invoke its constructor with the designated invocation handler. */try { Constructor cons = cl.getConstructor(constructorParams); return (Object) cons.newInstance(new Object[] { h });} catch (NoSuchMethodException e) { throw new InternalError(e.toString());} catch (IllegalAccessException e) { throw new InternalError(e.toString());} catch (InstantiationException e) { throw new InternalError(e.toString());} catch (InvocationTargetException e) { throw new InternalError(e.toString());} }
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
该方法有三个参数:第三个参数是一个Object类型的数组,它传递的是foo()的参数,第二个参数是Method类的对象,这个类要关注一下。
ublic Object invoke(Object obj, Object... args)throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable;
先写这些
- Java代理之代理模式
- java代理模式---静态代理
- java代理模式--动态代理
- 代理模式&java动态代理
- JAVA代理模式--静态代理
- JAVA代理模式--动态代理
- JAVA动态代理 代理模式
- Java代理模式-静态代理
- java代理模式-动态代理
- Java代理模式 静态代理 动态代理
- JAVA代理模式与动态代理模式
- JAVA代理模式与动态代理模式
- JAVA代理模式与动态代理模式
- JAVA代理模式与动态代理模式
- JAVA代理模式与动态代理模式
- JAVA代理模式与动态代理模式
- Java代理模式和kotlin代理模式
- Java中的代理模式
- 使用libxml解析HTML -- Hpple
- vb.net Datagridview 下拉框应用
- Sublime Text2解决中文乱码
- DHTMLXTree的使用
- re.findall and re.search的区别
- Java 代理模式
- 25招教HR解决员工入职流程及风险的各种问题
- Hdu 5119 HappyMatt Friends (2014年北京现场赛H题)
- 跟着实例学习设计模式(6)-生成器模式builder(创建型)
- oracle默认角色
- git 学习笔记5-add和commit命令
- ehcache2.5后hibernate多SessionFactory报错的解决
- 【枚举+贪心】【TOJ3981】【ICPC Balloons】
- HangOver