java-动态代理
在學(xué)習(xí)spring的AOP時候,動態(tài)代理那是必不可少的環(huán)節(jié)。
今天簡單介紹一下動態(tài)代理。
java動態(tài)代理是一種設(shè)計(jì)模式中代理模式的一種,幫助我們開發(fā)的一個工具吧。
*1.動態(tài)代理的優(yōu)勢:*
降低各個功能模塊之間的耦合度,提高開發(fā)的效率和方便程序的維護(hù)度。
和aop的思想和切合。
減少代碼量。
對靜態(tài)代理有個了解的讀者可能就知道,靜態(tài)代理的代碼量比較龐大,所以動態(tài)代理是靜態(tài)代理的升華。
2.動態(tài)代理的實(shí)現(xiàn)方式 
 jdk自帶的動態(tài)代理主要是通過實(shí)現(xiàn)InvocationHandler
2.1 InvocationHandler的主要方法
- Object invoke(Object proxy, 
 Method method,
 Object[] args)
 throws Throwable
- 在代理實(shí)例上處理方法調(diào)用并返回結(jié)果。在與方法關(guān)聯(lián)的代理實(shí)例上調(diào)用方法時,將在調(diào)用處理程序上調(diào)用此方法。 
2.2 方法詳細(xì)介紹
- 參數(shù): 
 proxy - 調(diào)用方法的代理實(shí)例對象 method - 代理實(shí)例對象調(diào)用的接口方法的 Method 實(shí)例對象。
 Method-對象的聲明類將是在其中聲明方法的接口,該接口可以是代理類賴以繼承方法的代理接口的超接口。
 args -包含傳入代理實(shí)例上方法調(diào)用的參數(shù)值的對象數(shù)組,如果接口方法不使用參數(shù),則為 null。
- 返回: 
 從代理實(shí)例的方法調(diào)用返回的值。
- 拋出: Throwable - 從代理實(shí)例上的方法調(diào)用拋出的異常。 
3.具體登陸日志小案例(基于JDK動態(tài)代理)
3.1 業(yè)務(wù)接口 Login
public interface Login {public void login(String name); }3.2 業(yè)務(wù)實(shí)現(xiàn)類 LoginImpl
public class LoginImpl implements Login{@Overridepublic void login(String name) {System.out.println("welcome "+name+", login success !!1");} }3.3 代理類 LoginProxy
public class LoginProxy implements InvocationHandler {private Object target;public LoginProxy(Object target) {this.target = target;}public static Object init(Object Object){return Proxy.newProxyInstance(Object.getClass().getClassLoader(),Object.getClass().getInterfaces(),new LoginProxy(Object));}/*** 切入點(diǎn) 對所有對象的方法都進(jìn)行調(diào)用* method.invoke方法對應(yīng)代理對象調(diào)用login方法* @param proxy 代理對象* @param method 代理對象的方法* @param args 代理對象調(diào)用接口方法的參數(shù)值* @return 代理對象調(diào)用方法的返回值* @throws Throwable*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {login(method);Object invoke = method.invoke(target, args);loginout(method);return invoke;}//日志的方法public void log(String msg){System.out.println(msg);}//執(zhí)行前日志public void login(Method method){log(method.getName()+"方法執(zhí)行之前調(diào)用的信息");}//執(zhí)行后日志public void loginout(Method method){log(method.getName()+"方法執(zhí)行之后調(diào)用的信息");}}3.4 測試類 LoginClient
public class LoginClient {public static void main(String[] args) {Login login = (Login) LoginProxy.init(new LoginImpl());login.login("zhangsan");} }3.5 執(zhí)行結(jié)果:
從上面的例子我們可以看到動態(tài)代理有效的減少了各個模塊的耦合度。 
 用于實(shí)現(xiàn)日志功能的代碼和用于實(shí)現(xiàn)登陸功能的代碼相互隔離。 
 只有在真正調(diào)用業(yè)務(wù)的時候并需要日志功能時候二者才發(fā)生聯(lián)系。 
 任何業(yè)務(wù)需要日志功能只需要通過代理類創(chuàng)建代理對象即可。
總結(jié): 
 代理對象機(jī)制是一種非常實(shí)用的設(shè)計(jì)模式,有利于程序的開發(fā)效率以及對于程序的后期維護(hù)。不必在關(guān)系各個模塊之間的相互制約關(guān)系。
總結(jié)
 
                            
                        - 上一篇: 只读文件系统
- 下一篇: GNU C中x++是原子操作吗?
