標籤:java之動態代理
一、動態代理引入
package cn2;public interface IUserDAO {/** * 登入方法 */public void login();/** * 註冊方法 */public void register();}package cn2;public class UserDAOImpl implements IUserDAO {@Overridepublic void login() {System.out.println("使用者登入");}@Overridepublic void register() {System.out.println("使用者註冊");}}package cn2;public class Test {public static void main(String[] args) {IUserDAO dao = new UserDAOImpl();dao.register();dao.login();}}
使用者註冊
使用者登入
如果我要給每個方法都增加許可權校正和日誌記錄的話,那麼代碼實現如下:
package cn2;public interface IUserDAO {/** * 登入方法 */public void login();/** * 註冊方法 */public void register();}package cn2;public class UserDAOImpl implements IUserDAO {@Overridepublic void login() {System.out.println("使用者登入");}@Overridepublic void register() {System.out.println("使用者註冊");}}package cn2;public class UserDAOImpl2 implements IUserDAO {private void actionCheck(){System.out.println("許可權檢查");}private void record(){System.out.println("日誌記錄");}@Overridepublic void login() {this.actionCheck();System.out.println("登入");this.record();}@Overridepublic void register() {this.actionCheck();System.out.println("註冊");this.record();}}package cn2;public class Test {public static void main(String[] args) {IUserDAO dao = new UserDAOImpl2();dao.register();dao.login();}}
許可權檢查
註冊
日誌記錄
許可權檢查
登入
日誌記錄
為什麼要單獨寫一個類去實現介面,並增加許可權校正和日誌記錄呢?因為我們在設計的時候,要保證對擴充功能開發,對修改代碼關閉的原則。我定義了一個新的類去實現介面,就是想擴充原來介面的功能,而不是在原有的實作類別上修改。
但是,如果都這樣設計,是很可怕的事情,如果需求一旦變更,那我們需要定義好多好多的實作類別,太複雜了。怎麼辦?
在生活中,我們會遇到很多問題,比如:我要租房子,但是我不認識房東,怎麼辦?找中介。同樣的道理,我自己不想在修改代碼去增加許可權檢查和日誌記錄的功能,那麼我找一個代理對象去幫我實現不就可以了嗎?
動態代理:就是在程式運行過程中產生的這個對象。
在Java中java.lang.reflect包下提供了一個Proxy類和一個InvocationHandler介面,通過使用這個類和介面接可以產生動態代理對象。JDK只針對介面做代理。
Proxy類中的方法建立動態代理對象
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
最終會調用InvocationHandler的方法
Object invoke(Object proxy,Method method,Object[] args)
package cn2;public interface IUserDAO {/** * 登入方法 */public void login();/** * 註冊方法 */public void register();}package cn2;public class UserDAOImpl implements IUserDAO {@Overridepublic void login() {System.out.println("使用者登入");}@Overridepublic void register() {System.out.println("使用者註冊");}}package cn2;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class MyInvocationHandler implements InvocationHandler {private Object target;public MyInvocationHandler(Object target) {this.target = target;}/** *返回動態代理對象 */@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {System.out.println("許可權檢查");Object invoke = method.invoke(target, args);System.out.println("日誌記錄");return invoke;}}package cn2;import java.lang.reflect.Proxy;public class Test {public static void main(String[] args) {//使用動態代理之前IUserDAO dao = new UserDAOImpl();dao.register();dao.login();System.out.println("-------------------");//使用動態代理之後IUserDAO proxy = (IUserDAO)Proxy.newProxyInstance(dao.getClass().getClassLoader(), dao.getClass().getInterfaces(), new MyInvocationHandler(dao));proxy.register();proxy.login();}}
使用者註冊
使用者登入
-------------------
許可權檢查
使用者註冊
日誌記錄
許可權檢查
使用者登入
日誌記錄
本文出自 “11831428” 部落格,請務必保留此出處http://11841428.blog.51cto.com/11831428/1878267
java之動態代理