在目前的Java開(kāi)發(fā)包中包含了對(duì)動(dòng)態(tài)代理的支持,但是其實(shí)現(xiàn)只支持對(duì)接口的的實(shí)現(xiàn)。
其實(shí)現(xiàn)主要通過(guò)是java.lang.reflect.Proxy類(lèi)和java.lang.reflect.InvocationHandler接口。
Examda提示: Proxy類(lèi)主要用來(lái)獲取動(dòng)態(tài)代理對(duì)象,InvocationHandler接口用來(lái)約束調(diào)用者實(shí)現(xiàn),如下,HelloWorld接口定義的業(yè)務(wù)方法,HelloWorldImpl是HelloWorld接口的實(shí)現(xiàn),HelloWorldHandler是 InvocationHandler接口實(shí)現(xiàn)。代碼如下:
業(yè)務(wù)接口:
public interface HelloWorld {
void sayHelloWorld() ;
}
業(yè)務(wù)接口實(shí)現(xiàn):
public class HelloWorldImpl implements HelloWorld {
public void sayHelloWorld() {
System.out.println("Hello World!");
}
}
InvocationHandler實(shí)現(xiàn),需要在接口方法調(diào)用前后加入一部份處理工作,這里僅僅在方法調(diào)用前后向后臺(tái)輸出兩句字符串,其代碼如下:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class HelloWorldHandler implements InvocationHandler {
//要代理的原始對(duì)象
private Object objOriginal;
/**
* 構(gòu)造函數(shù)。
* @param obj Examda提示: 要代理的原始對(duì)象。
*/
public HelloWorldHandler(Object obj) {
this.objOriginal = obj ;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result ;
//方法調(diào)用之前
doBefore();
//調(diào)用原始對(duì)象的方法
result = method.invoke(this.objOriginal ,args);
//方法調(diào)用之后
doAfter();
return result ;
}
private void doBefore() {
System.out.println("before method invoke!");
}
private void doAfter() {
System.out.println("after method invoke!");
}
}
測(cè)試代碼:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
HelloWorld hw = new HelloWorldImpl();
InvocationHandler handler = new HelloWorldHandler(hw);
HelloWorld proxy = (HelloWorld) Proxy.newProxyInstance(
hw.getClass().getClassLoader(),
hw.getClass().getInterfaces(),
handler);
proxy.sayHelloWorld();
}
}
Ø 首先獲取一個(gè)業(yè)務(wù)接口的實(shí)現(xiàn)對(duì)象;
Ø 獲取一個(gè)InvocationHandler實(shí)現(xiàn),此處是HelloWorldHandler對(duì)象;
Ø 創(chuàng)建動(dòng)態(tài)代理對(duì)象;
Ø 通過(guò)動(dòng)態(tài)代理對(duì)象調(diào)用sayHelloWorld()方法,此時(shí)會(huì)在原始對(duì)象HelloWorldImpl. sayHelloWorld()方法前后輸出兩句字符串。
運(yùn)行測(cè)試類(lèi)輸出如下:
before method invoke!
Hello World!
after method invoke!
此處Test類(lèi)中的方法調(diào)用代碼比較多,在我們的實(shí)際應(yīng)用中可以通過(guò)配置文件來(lái)來(lái)簡(jiǎn)化客戶端的調(diào)用實(shí)現(xiàn)。另外也可以通過(guò)動(dòng)態(tài)代理來(lái)實(shí)現(xiàn)簡(jiǎn)單的AOP。
其實(shí)現(xiàn)主要通過(guò)是java.lang.reflect.Proxy類(lèi)和java.lang.reflect.InvocationHandler接口。
Examda提示: Proxy類(lèi)主要用來(lái)獲取動(dòng)態(tài)代理對(duì)象,InvocationHandler接口用來(lái)約束調(diào)用者實(shí)現(xiàn),如下,HelloWorld接口定義的業(yè)務(wù)方法,HelloWorldImpl是HelloWorld接口的實(shí)現(xiàn),HelloWorldHandler是 InvocationHandler接口實(shí)現(xiàn)。代碼如下:
業(yè)務(wù)接口:
public interface HelloWorld {
void sayHelloWorld() ;
}
業(yè)務(wù)接口實(shí)現(xiàn):
public class HelloWorldImpl implements HelloWorld {
public void sayHelloWorld() {
System.out.println("Hello World!");
}
}
InvocationHandler實(shí)現(xiàn),需要在接口方法調(diào)用前后加入一部份處理工作,這里僅僅在方法調(diào)用前后向后臺(tái)輸出兩句字符串,其代碼如下:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class HelloWorldHandler implements InvocationHandler {
//要代理的原始對(duì)象
private Object objOriginal;
/**
* 構(gòu)造函數(shù)。
* @param obj Examda提示: 要代理的原始對(duì)象。
*/
public HelloWorldHandler(Object obj) {
this.objOriginal = obj ;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result ;
//方法調(diào)用之前
doBefore();
//調(diào)用原始對(duì)象的方法
result = method.invoke(this.objOriginal ,args);
//方法調(diào)用之后
doAfter();
return result ;
}
private void doBefore() {
System.out.println("before method invoke!");
}
private void doAfter() {
System.out.println("after method invoke!");
}
}
測(cè)試代碼:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
HelloWorld hw = new HelloWorldImpl();
InvocationHandler handler = new HelloWorldHandler(hw);
HelloWorld proxy = (HelloWorld) Proxy.newProxyInstance(
hw.getClass().getClassLoader(),
hw.getClass().getInterfaces(),
handler);
proxy.sayHelloWorld();
}
}
Ø 首先獲取一個(gè)業(yè)務(wù)接口的實(shí)現(xiàn)對(duì)象;
Ø 獲取一個(gè)InvocationHandler實(shí)現(xiàn),此處是HelloWorldHandler對(duì)象;
Ø 創(chuàng)建動(dòng)態(tài)代理對(duì)象;
Ø 通過(guò)動(dòng)態(tài)代理對(duì)象調(diào)用sayHelloWorld()方法,此時(shí)會(huì)在原始對(duì)象HelloWorldImpl. sayHelloWorld()方法前后輸出兩句字符串。
運(yùn)行測(cè)試類(lèi)輸出如下:
before method invoke!
Hello World!
after method invoke!
此處Test類(lèi)中的方法調(diào)用代碼比較多,在我們的實(shí)際應(yīng)用中可以通過(guò)配置文件來(lái)來(lái)簡(jiǎn)化客戶端的調(diào)用實(shí)現(xiàn)。另外也可以通過(guò)動(dòng)態(tài)代理來(lái)實(shí)現(xiàn)簡(jiǎn)單的AOP。