java動(dòng)態(tài)代理JDK實(shí)現(xiàn)
步驟
定義接口
public interface Hello {
void sayHi();
}
目標(biāo)類(實(shí)現(xiàn)上面的接口)
public class HelloImpl implements Hello{
public void sayHi() {
System.out.println("睡你麻痹起來(lái)嗨");
}
}
實(shí)際處理類
實(shí)現(xiàn)InvocationHandler接口
public class DynamicProxy implements InvocationHandler {
private Object target;
public DynamicProxy(Object target){
this.target=target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object result=method.invoke(target,args);
after();
return result;
}
public void before(){
System.out.println("不想起床");
}
public void after(){
System.out.println("就算起來(lái)了也嗨不起來(lái)");
}
}
JDK的Proxy類創(chuàng)建代理類
public static void main(String[] args){
Hello hello=new HelloImpl();
DynamicProxy dynamicProxy=new DynamicProxy(hello);
Hello helloProxy=(Hello) Proxy.newProxyInstance(hello.getClass().getClassLoader(),hello.getClass().getInterfaces(),dynamicProxy);
helloProxy.sayHi();
}
優(yōu)化
可以看到Proxy動(dòng)態(tài)代理創(chuàng)建過(guò)程中需要的參數(shù):hello蚁阳,dynamicProxy在DynamicProxy類中都有德召,可以做如下簡(jiǎn)化。
DynamicProxy
public <T> T getProxy(){
return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
優(yōu)點(diǎn)
如果一個(gè)接口有多個(gè)實(shí)現(xiàn)類索绪,對(duì)這些實(shí)現(xiàn)類創(chuàng)建代理類只需要這一個(gè)DynamicProxy就好了,不需要做其他的修改裆针。如果需要在方法的前后做不同的事情帐萎,只用定義不同的DynamicProxy校读,里面的before和after方法完成相應(yīng)的功能就好了。就算接口發(fā)生了變化丧靡,代理類也不用變化蟆沫。
缺點(diǎn)
如果要代理沒(méi)有實(shí)現(xiàn)任何接口的類就不行了。