Java代理模式實現的三種方式
阿新 • • 發佈:2018-12-18
1.靜態代理
1.1.定義一個介面
public interface IWorkerService {
void doSomething();
}
1.2.定義一個實現
public class WorkerServiceImpl implements IWorkerService{
public void doSomething() {
System.out.println("work hard");
}
}
1.3.定義一個靜態代理類
public class WorkerProxy implements IWorkerService{
private IWorkerService workerService;
public WorkerProxy(IWorkerService workerService){
this.workerService = workerService;
}
public void doSomething() {
System.out.println("start work");
workerService.doSomething();
System.out.println("end work");
}
}
1.4測試
WorkerProxy proxy = new WorkerProxy(new WorkerServiceImpl());
proxy.doSomething();
2.JDK動態代理
2.1 JDK動態代理類
基於JDK動態代理介面實現一個動態代理類,定義JDKProxy類實現InvocationHandler介面。
public class JDKProxy<T> implements InvocationHandler{
private Object target;
public T getProxy(Object t){
this.target = t;
// 建立代理物件
return (T) Proxy.newProxyInstance(t.getClass().getClassLoader(), t.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("dynamic proxy start");
method.invoke(target, args);
System.out.println("dynamic proxy end");
return null;
}
}
2.2測試
IWorkerService workerProxy = new JDKProxy<IWorkerService>().getProxy(new WorkerServiceImpl());
workerProxy.doSomething();
3.cglib代理
3.1代理實現
定義CglibProxy類,實現MethodInterceptor介面。
public class CglibProxy implements MethodInterceptor{
public <T> T getProxy(Class<T> clz){
// 通過生成子類的方式代理
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clz);
enhancer.setCallback(this);
T proxy = (T) enhancer.create();
return proxy;
}
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.print("cglib proxy start");
Object proxy = methodProxy.invokeSuper(o, objects);
System.out.print("cglib proxy end");
return proxy;
}
}
3.2.測試
IWorkerService cglibProxy = new CglibProxy().getProxy(WorkerServiceImpl.class);
cglibProxy.doSomething();
WorkerServiceImpl workerService = new CglibProxy().getProxy(WorkerServiceImpl.class);
workerService.doSomething();
4.小結
- 靜態代理類只能為一個被代理類服務,如果需要代理的類比較多,需要為每一個類實現代理類。靜態代理類可以直接使用,效率較高。
- jdk動態代理需要被代理類實現代理介面通過反射實現代理方法,消耗一定系統性能,但是無需編寫過多代理類,避免程式碼重複,更加靈活。
- Cglib實現原理是通過動態生成子類位元組碼來實現,比反射要快。由於cglib生成代理相當於被代理類的子類,所以被代理類不能是final型別,被代理的方法也不能是final型別。