设计形式:代理模式
设计模式:代理模式
1,抽象角色
package com.langsin.proxy; //抽象角色 public abstract class Subject { abstract public void request(); }
2,真实角色
package com.langsin.proxy; //真实角色 public class RealSubject extends Subject{ public RealSubject() { } public void request(){ System.out.println("from real subject!"); } }
3,代理角色
package com.langsin.proxy; //代理角色 public class ProxySubject extends Subject{ private RealSubject realSubject = new RealSubject(); public ProxySubject() { } public void request(){ preRequest(); if(realSubject == null){ realSubject = new RealSubject(); } realSubject.request(); postRequest(); } public void preRequest(){ System.out.println("pre request!"); } public void postRequest(){ System.out.println("post request!"); } public static void main(String[] args) { Subject subject = new ProxySubject(); subject.request(); } }
测试类:
package com.langsin.proxy; public class Client { public static void main(String[] args) { Subject subject = new ProxySubject(); subject.request(); } }
打印结果
pre request! from real subject! post request!
理解: 真实角色就好像一个具体做事的局长,如批文等。而代理角色就好像其秘书,外部将具体的任务交给秘书,由秘书再转交给局长来执行。秘书可以局长执行任务前后附加一些功能。这就是代理角色。
package com.langsin.dynamicproxy; //抽象角色(上一例是抽象类)现在改为接口。 public interface Subject { public void request(); }
package com.langsin.dynamicproxy; //真实角色 public class RealSubject implements Subject{ public RealSubject(){ } public void request() { System.out.println("from real subject!"); } }
package com.langsin.dynamicproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; //代理处理器 /* * 该代理类内部属性sub为Object类,实际使用时通过该类的构造函数DynamicSubject(Object obj)对其赋值; * 此外,在该类还实现了invoke方法,该方法中的method.invoke(sub,args); * 其实就是调用被代理对象的将要被执行的方法,方法参数sub是实际的被代理对象, * args为执行被代理对象相应操作所需的参数。 * 通过动态代理类,我们可以在调用之前或之后执行一些相关操作 */ public class DynamicSubject implements InvocationHandler{ private Object sub; public DynamicSubject() { } public DynamicSubject(Object obj) { this.sub = obj; } //此方法由JAVA动态调用 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before invoke!"+method); method.invoke(sub, args); System.out.println("after invoke!"+method); return null; } }
package com.langsin.dynamicproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; //客户端 public class Clent { public static void main(String[] args) { RealSubject rs = new RealSubject(); //在这里指定被代理类 InvocationHandler ds = new DynamicSubject(rs); //一次性生成代理,以下内容可以运行时动态改变,这就是动态代理的优势 Subject subject = (Subject) Proxy.newProxyInstance(rs.getClass().getClassLoader(), rs.getClass().getInterfaces(), ds); subject.request(); } }
打印结果为:
before invoke!public abstract void com.langsin.dynamicproxy.Subject.request() from real subject! after invoke!public abstract void com.langsin.dynamicproxy.Subject.request()
package com.langsin.vectorproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.List; import java.util.Vector; public class VectorProxy implements InvocationHandler{ private Object proxyobj; public VectorProxy(Object obj) { proxyobj = obj; } public static Object factory(Object obj){ Class<?> cls = obj.getClass(); return Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), new VectorProxy(obj)); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before !"+method); if(args != null){ for (int i = 0; i < args.length; i++) { System.out.println(args[i]); } } Object object = method.invoke(proxyobj, args); System.out.println("after !"+method); return object; } public static void main(String[] args) { List<String> v = (List<String>)factory(new Vector<String>(10)); v.add("new"); v.add("york"); System.out.println(v.hashCode()); v.remove(0); System.out.println(v); } }
打印结果:
before !public abstract boolean java.util.List.add(java.lang.Object) new after !public abstract boolean java.util.List.add(java.lang.Object) before !public abstract boolean java.util.List.add(java.lang.Object) york after !public abstract boolean java.util.List.add(java.lang.Object) before !public native int java.lang.Object.hashCode() after !public native int java.lang.Object.hashCode() 7093744 before !public abstract java.lang.Object java.util.List.remove(int) 0 after !public abstract java.lang.Object java.util.List.remove(int) before !public java.lang.String java.lang.Object.toString() after !public java.lang.String java.lang.Object.toString() [york]
package com.langsin.foo; public interface Foo { void doAction(); }
package com.langsin.foo; public class FooImpl implements Foo { public FooImpl() { } public void doAction() { System.out.println("in FooImp1.doAction()"); } }
package com.langsin.foo; public class FooImpl2 implements Foo { public FooImpl2() { } public void doAction() { System.out.println("in FooImp2.doAction()"); } }
package com.langsin.foo; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class CommonInvocationHandler implements InvocationHandler { // 动态执行对象,需要回调的对象 private Object target; // 支持构造子注射 public CommonInvocationHandler() { } // 支持构造子注射 public CommonInvocationHandler(Object target) { setTarget(target); } // 采用setter方法注射 public void setTarget(Object target) { this.target = target; } /** * 调用proxy中指定的方法method,并传入参数列表args * @param proxy 代理类的类型,例如定义对应method的代理接口 * @param method被代理的方法 * @param args调用被代理方法的参数 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(target, args); } }
package com.langsin.foo; import java.lang.reflect.Proxy; public class Demo { public static void main(String[] args){ // 1.通用的动态代理实现 CommonInvocationHandler handler = new CommonInvocationHandler(); Foo f; // 2.接口实现1 handler.setTarget(new FooImpl()); // 方法参数说明:代理类、代理类实现的接口列表、代理类的处理器 // 关联代理类、代理类中接口方法、处理器,当代理类中接口方法被调用时,会自动分发到处理器的invoke方法 // 如果代理类没有实现指定接口列表,会抛出非法参数异常 f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class[] { Foo.class },handler); f.doAction(); // 3.接口实现2 handler.setTarget(new FooImpl2()); f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class[] { Foo.class },handler); f.doAction(); } }