Java動態代理模式 -- 保護代理
阿新 • • 發佈:2018-08-18
dna 接口 private 意義 except handle loader param lac
意義
將接口的調用統一到一個函數裏處理,然後再去具體實例調用相應的方法,充當一個分發器的作用
user -> handler -> method
字典
動態:指的是在程序運行時才創建代理類
代理:與被代理類具有相同的屬性,也就是被代理類有run方法,它也有run方法
保護代理:限制接口類的某些方法給特定的對象使用
Proxy類:Java反射包自帶,其中newProxyInstance可以返回接口實現類的實例
組成
1.接口
Person類:其中有name與score相關的方法
自己本人可以修改名字但不能修改分數
別人可以修改分數不能修改名字
public interface PersonBean { String getName();void setName(String name); int getScore(); void setScore(int score); }
2.實現接口的類
public class PersonBeanImpl implements PersonBean { private String name; private int score; public PersonBeanImpl (){ } public PersonBeanImpl (String name,int score){ this.name = name;this.score = score; } public String getName (){ return name; } public void setName (String name){ this.name = name; } public int getScore (){ return score; } public void setScore (int score){ this.score = score; } }
3.實現InvocationHandler的handler類
它的invoke方法利用反射,PersonBean的方法調用時會來調用invoke,因此可以在invoke方法體實現相應邏輯,
實例中就是限定某些方法允許調用,某些方法會拋出異常
3.1 自身handler:當創建這個handler實例時,就說明只能修改name不能修改score
public class OwnInvocationHandler implements InvocationHandler { // 需要代理的對象 private PersonBean personBean; OwnInvocationHandler (PersonBean personBean){ this.personBean = personBean; } // 代理設置規則 public Object invoke (Object proxy ,Method method, Object[] args) throws Throwable{ String methodName = method.getName(); // 自己不能設置自己的分數 if ("setScore".equals(methodName)) { throw new IllegalAccessException("自己不能給自己打分"); } else { return method.invoke(personBean, args); } } }
3.2 他人handler:當創建這個handler實例時,就說明只能修改score不能修改name
public class OtherInvocationHandler implements InvocationHandler { // 需要代理的對象 private PersonBean personBean; OtherInvocationHandler (PersonBean personBean){ this.personBean = personBean; } // 代理設置規則 public Object invoke (Object proxy ,Method method, Object[] args) throws Throwable{ String methodName = method.getName(); // 不能修改別人的名字 if ("setName".equals(methodName)) { throw new IllegalAccessException("不能修改別人的名字"); } else { return method.invoke(personBean, args); } } }
4.生產handler類的工廠
通過Proxy的newProxyInstance獲取PersonBean對象
它的主要作用:將傳入的personBean與指定的InvocationHandler綁定,當PersonBean調用方法時,會去InvocationHandler調用invoke方法
public class ProxyFactory { /** * 獲得 個人 代理 * @param personBean * @return */ public PersonBean getOwnerProxy(PersonBean personBean) { return (PersonBean)Proxy.newProxyInstance(personBean.getClass().getClassLoader(), personBean.getClass().getInterfaces(), new OwnInvocationHandler(personBean)); } /** * 獲得 其他人 代理 * @param personBean * @return */ public PersonBean getOtherProxy(PersonBean personBean) { return (PersonBean)Proxy.newProxyInstance(personBean.getClass().getClassLoader(), personBean.getClass().getInterfaces(), new OtherInvocationHandler(personBean)); } }
參考《Head First 設計模式》 -- P474
Java動態代理模式 -- 保護代理