1. 程式人生 > >Java代理模式實現的三種方式

Java代理模式實現的三種方式

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.小結

  1. 靜態代理類只能為一個被代理類服務,如果需要代理的類比較多,需要為每一個類實現代理類。靜態代理類可以直接使用,效率較高。
  2. jdk動態代理需要被代理類實現代理介面通過反射實現代理方法,消耗一定系統性能,但是無需編寫過多代理類,避免程式碼重複,更加靈活。
  3. Cglib實現原理是通過動態生成子類位元組碼來實現,比反射要快。由於cglib生成代理相當於被代理類的子類,所以被代理類不能是final型別,被代理的方法也不能是final型別。