Head First 设计模式学习笔记(十三)代理模式 续
?
?
???1. 在java.lang.reflect包下,定义了自己的代理。利用这个包下的类,我们可以在运行时动态地创建一个代理类,实现一个或多个接口。并将方法的调用转发到你所指定的类。因为实际代理是在运行时创建的,所以称为:动态代理。
?
????
?
??? Proxy:完全由java产生的,而且实现了完整的subject接口。
??? InvocationHandler:Proxy上的任何方法调用都会被传入此类,InvocationHandler控制对RealSubject的访问。
??? 因为Java已经帮助我们创建了Proxy类,我们需要有办法告诉Proxy类你要做什么,我们不能像以前一样把代码写入到Proxy类中,因为Proxy类不是我们实现的。那么我们应该放在哪里?放在InvocationHandler类中,InvocationHandler类是响应代理的任何调用。我们可以吧InvocationHandler想成是代理收到方法调用后,请求做实际工作的对象。
???
?2. java.lang.reflect.InvocationHandler
??? 被代理实例所实现的一个接口,内部只有一个invoke()方法,签名如下;
??? Java代码
??? public Object invoke(Object proxy, Method method, Object[] args)
??? 当代理的方法被调用的时候,代理就会把这个调用转发给InvocationHandler,也就会调用它的invoke()方法。
??
? 3. java.lang.reflect.Proxy
??? 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类,我们经常使用的静态方式是:
??? Java代码
??? newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
???
?4. 示例:
??? 情形:自己可以查看修改姓名性别,但是不能修改rate。他人可以查看姓名,性别以及修改rate,但是不能修改姓名性别。
?
??? 1、接口
public interface Person { String getName(); String getGender(); void setName(String name); void setGender(String gender); void setRate(int rate); int getRate(); }
?
??? 2、实现类
??
public class PersonImpl implements Person {String name;String gender;String interests;int rate;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public String getInterests() {return interests;}public void setInterests(String interests) {this.interests = interests;}public int getRate() {return rate;}public void setRate(int rate) {this.rate = rate;}}
?
3、定义OwnerInvocationHandler类,表示如果为本人,则可以进行修改查看姓名性别。
?
public class OwnerInvocationHandler implements InvocationHandler {private Person personBean;public OwnerInvocationHandler(Person personBean) {this.personBean = personBean;}public Object invoke(Object proxy, Method method, Object[] args)throws IllegalAccessException {try {if (method.getName().startsWith("get")) {// 如果方法名为get,就调用person类内的get相应方法return method.invoke(personBean, args);} else if (method.getName().equals("setRate")) { // 如果方法是setRate,则抛出异常throw new IllegalAccessException("access deny");} else if (method.getName().startsWith("set")) { // 如果为set,就调用person类内的set相应方法return method.invoke(personBean, args);} else {System.out.println("non method invoke");}} catch (InvocationTargetException e) {e.printStackTrace();}return null;}}
?
4、定义NonInvocationHandler类,表示如果不为本人,则可以进行查看姓名性别和修改rate??
??
public class NonInvocationHandler implements InvocationHandler {private Person person;public NonInvocationHandler(Person person) {this.person = person;}public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {if (method.getName().startsWith("setRate")) {return method.invoke(person, args);} else if (method.getName().startsWith("get")) {return method.invoke(person, args);} else {System.out.println("non method invoke");return null;}}}
?
?? 5、测试类
?
public class MyDynamicProxy {public Person getOwnerPersonBeanProxy(Person person) {return (Person) Proxy.newProxyInstance(person.getClass().getClassLoader(), person.getClass().getInterfaces(),new OwnerInvocationHandler(person));}public Person getNonPersonBeanProxy(Person person) {return (Person) Proxy.newProxyInstance(person.getClass().getClassLoader(), person.getClass().getInterfaces(),new NonInvocationHandler(person));}public static void main(String[] args) {MyDynamicProxy mdp = new MyDynamicProxy();mdp.test();}public void test() {//Person person = getPersonBeanFromDB1();Person personProxy = getOwnerPersonBeanProxy(person);System.out.println(personProxy.getName());try {personProxy.setRate(2);} catch (Exception e) {System.out.println("can not setRate");}//Person person1 = getPersonBeanFromDB1();Person personProxy2 = getNonPersonBeanProxy(person1);System.out.println(personProxy2.getName());personProxy2.setRate(2);System.out.println(personProxy2.getRate());}private Person getPersonBeanFromDB1() {Person pb = new PersonImpl();pb.setName("remy");pb.setGender("girl");pb.setRate(1);return pb;}}
?
?
还可以参考 http://www.iteye.com/topic/961057
http://www.iteye.com/topic/1116657
?
写的非常好!