Java静态代理、动态代理实例

来源:互联网 发布:定做t恤 知乎 编辑:程序博客网 时间:2024/05/05 07:23

采用Java代理模式,代理类通过调用委托类对象的方法,来提供特定的服务。委托类需要实现一个业务接口,代理类返回委托类的实例接口对象。

按照代理类的创建时期,可以分为:静态代理和动态代理。

所谓静态代理: 指程序员创建好代理类,编译时直接生成代理类的字节码文件。

所谓动态代理: 在程序运行时,通过反射机制动态生成代理类。

 

一、静态代理类实例:

1、Serivce.java

 

Java代码 
  1. package com.ibm.delegate;  
  2.   
  3. /** 
  4.  * 定义一个服务接口 
  5.  * @author IBM 
  6.  */  
  7. public interface Service {  
  8.       
  9.     /** 
  10.      * 查询日期 
  11.      */  
  12.     public String queryDate();  
  13.     /** 
  14.      * 计算两个整数之差 
  15.      */  
  16.     public int sub(int a, int b);  
  17. }  

 

2、ServiceImpl.java

 

Java代码 
  1. package com.ibm.delegate;  
  2.   
  3. import java.util.Date;  
  4.   
  5. /** 
  6.  * 委托类需要实现服务接口(必须) 
  7.  * @author IBM 
  8.  */  
  9. public class CountImpl implements Service {  
  10.   
  11.     @Override  
  12.     public String queryDate() {  
  13.         return new Date().toString();  
  14.     }  
  15.   
  16.     @Override  
  17.     public int sub(int a, int b) {  
  18.         return a-b;  
  19.     }  
  20.       
  21.     public void ownMethod(){  
  22.         System.out.println("It's my own method");  
  23.     }  
  24. }  
3、ServiceProxy.java

 

 

Java代码 
  1. package com.ibm.staticproxy;  
  2.   
  3. import com.ibm.delegate.Serivce;  
  4. import com.ibm.delegate.CountImpl;  
  5.   
  6. /** 
  7.  * @author IBM 
  8.  * 静态代理类 
  9.  */  
  10. public class SerivceProxy implements Service {  
  11.     private CountImpl countImpl;  
  12.       
  13.     public SerivceProxy(CountImpl countImpl){  
  14.         this.countImpl = countImpl;  
  15.     }  
  16.       
  17.     @Override  
  18.     public String queryDate() {  
  19.         return countImpl.queryDate();  
  20.     }  
  21.   
  22.     @Override  
  23.     public int sub(int a, int b) {  
  24.         return countImpl.sub(a, b);  
  25.     }  
  26.       
  27.     public void ownMethod(){  
  28.         System.out.println("It's my own method");  
  29.     }  
  30. }  
4、ServiceTest.java(测试类)

 

 

Java代码 
  1. package com.ibm;  
  2.   
  3. import com.ibm.delegate.ServiceImpl;  
  4. import com.ibm.staticproxy.ServiceProxy;  
  5.   
  6. public class ServiceTest {  
  7.   
  8.     /** 
  9.      * @param args 
  10.      */  
  11.     public static void main(String[] args) {  
  12.         //创建委托类实例,即被代理的类对象  
  13.         ServiceImpl target = new ServiceImpl();  
  14.         //创建静态代理类  
  15.         ServiceProxy proxy = new ServiceProxy(target);  
  16.         String date = proxy.queryDate();  
  17.         System.out.println(date);  
  18.         int result = proxy.sub(1020);  
  19.         System.out.println("10-20 = "+result);  
  20.         proxy.ownMethod();  
  21.     }  
  22. }  

静态代理类的特点: 代理类和委托类实现了相同的接口,代理类通过委托类实现了相同的方法。这样就出现了大量的代码重复。而且代理类只能为特定的接口(Service)服务。

 


动态代理实例:

3、ServiceProxy.java

 

Java代码 
  1. package com.ibm.dynamicproxy;  
  2.   
  3. import java.lang.reflect.InvocationHandler;  
  4. import java.lang.reflect.Method;  
  5. import java.lang.reflect.Proxy;  
  6.   
  7. public class ServiceProxy implements InvocationHandler {  
  8.   
  9.     private Object target;  
  10.       
  11.     public ServiceProxy(Object target){  
  12.         this.target = target;  
  13.     }  
  14.       
  15.     @Override  
  16.     public Object invoke(Object proxy, Method method, Object[] args)  
  17.             throws Throwable {  
  18.         Object result = null;  
  19.         result = method.invoke(target, args);  
  20.         return result;  
  21.     }  
  22.       
  23.     /** 
  24.      * @param target 
  25.      * @return 返回委托类接口的实例对象 
  26.      */  
  27.     public Object getProxyInstance(){  
  28.         return Proxy.newProxyInstance(target.getClass().getClassLoader(),   
  29.                 target.getClass().getInterfaces(), this);  
  30.     }  
  31. }  
4、ServiceTest.java(测试类)

 

 

Java代码 
  1. package com.ibm;  
  2.   
  3. import com.ibm.delegate.Service;  
  4. import com.ibm.delegate.ServiceImpl;  
  5. import com.ibm.dynamicproxy.ServiceProxy;  
  6.   
  7. public class ServiceTest {  
  8.   
  9.     /** 
  10.      * @param args 
  11.      */  
  12.     public static void main(String[] args) {  
  13.         //创建委托类实例,即被代理的类对象  
  14.         ServiceImpl target = new ServiceImpl();  
  15.         //创建动态代理类  
  16.         ServiceProxy proxy = new ServiceProxy(target);  
  17.         Service service = (Service) proxy.getProxyInstance();  
  18.         String date = service.queryDate();  
  19.         System.out.println(date);  
  20.         int result = service.sub(1020);  
  21.         System.out.println("10-20 = "+result);  
  22.     }  
  23. }  

 

动态代理: 代理类需要实现InvocationHandler接口。

使用场合举例: 如果需要委托类处理某一业务,那么我们就可以先在代理类中,对客户的权限、各类信息先做判断,如果不满足某一特定条件,则将其拦截下来,不让其代理。

 

修改两个方法,做测试:

ServiceImpl.java

 

Java代码 
  1. public String ownMethod(){  
  2.     System.out.println("It's my own method");  
  3.     return "user";  
  4. }  

 

ServiceProxy.java

 

Java代码 
  1. @Override  
  2. public Object invoke(Object proxy, Method method, Object[] args)  
  3.         throws Throwable {  
  4.     Object result = null;  
  5.     if(!(target instanceof ServiceImpl)){  
  6.         System.out.println("不能代理该对象");  
  7.         return result;  
  8.     }else if(!((ServiceImpl)target).ownMethod().equals("admin")){  
  9.         System.out.println("权限不够");  
  10.         return result;  
  11.     }  
  12.     result = method.invoke(target, args);  
  13.     return result;  
  14. }