浅谈java代理类proxy

代理类的作用,顾名思义,代理类,是类的代理,将类给代理,不直接调用类的方法,而通过代理来调用。
构造方法:
private Proxy() {
    }

protected Proxy(InvocationHandler h) {
 this.h = h;
    }
由这个可以知道这个类是不能直接new 的,查看api,提供调用见下

Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。

创建某一接口 Foo 的代理:

     InvocationHandler handler = new MyInvocationHandler(...);
     Class proxyClass = Proxy.getProxyClass(
         Foo.class.getClassLoader(), new Class[] { Foo.class });
     Foo f = (Foo) proxyClass.
         getConstructor(new Class[] { InvocationHandler.class }).
         newInstance(new Object[] { handler });
 
或使用以下更简单的方法:
     Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
                                          new Class[] { Foo.class },
                                          handler)

代理类可以用作aop做,调用方法前的一些操作,相当于是一个before操作,当通过代理类获取到对象,用该对象调用代理方法将会有一个inoke操作 。实现invoke操作需要实现InvocationHandler接口,这也是实现代理方法的很重要的一步,代理的方法需要通过该接口的实现类进行invoke操作

下面创建一个使用代理类的简单实例。实例实现的目标是。在老师工作的时候是上课,在工作之前需要准备课前操作。

详细步骤如下:

1.创建work接口IWork,该接口定义一个工作方法,

2.创建IWork接口的实现类TeacherWoke,

3.将work方法交给work代理类代理,创建WorkProxy代理类

4.实现InvocationHandler接口

第一步创建接口:

public interface IWork {
 
 public void work();
 
}

第二部实现接口

public class TeacherWoke implements IWork{

 @Override
 public void work() {
  // TODO Auto-generated method stub
  System.out.println("老师上上课");
 }
 

}


第三部创建代理类:

public class WorkProxy {
 public IWork work;
 public WorkProxy(IWork work) {
  // TODO Auto-generated constructor stub
  this.work = work;
 }
 
 public IWork createWorkProxy(){
  InvocationHandler handler = new WorkHandler(work);
  Class[] iterfaces = new Class[]{IWork.class};
  return (IWork)Proxy.newProxyInstance(IWork.class.getClassLoader(), iterfaces, handler);
 }

}

第四部实现InvocationHandler:接口

public class WorkHandler implements InvocationHandler {
 
 
 private IWork work;
 public WorkHandler(IWork work) {
  // TODO Auto-generated constructor stub
  this.work=work;
 }

 @Override
 public Object invoke(Object proxy, Method method, Object[] args)
   throws Throwable {
  // TODO Auto-generated method stub
  //老师工作之前需要先准备课件,讲义,等课前准备
  preWork();
  
  Object ret =  method.invoke(work,args);
  
  return ret;
  
  
 }

 private void preWork() {
  // TODO Auto-generated method stub
  System.out.println("老师工作之前需要先准备课件,讲义,等课前准备");
  
 }

}

测试代码如下:
public class TestWorkClient {
 
 
 @Test
 public void testWorkProxy() throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, InterruptedException{
  
  IWork teachwork = new TeacherWoke();
  WorkProxy workproxy = new WorkProxy(teachwork);
  IWork work = workproxy.createWorkProxy();
  work.work();
 }
 
 

}
特别说明
对代码进行一些说明类WorkHandler中的invoke方法的api如下
参数: proxy - 在其上调用方法的代理实例 method - 对应于在代理实例上调用的接口方法的 Method 实例。 Method 对象的声明类将是在其中声明方法的接口,该接口可以是代理类赖以继承方法的代理接口的超接口。 args - 包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为 null。基本类型的参数被包装在适当基本包装器类(如 java.lang.Integerjava.lang.Boolean)的实例中。 返回:从代理实例的方法调用返回的值。如果接口方法的声明返回类型是基本类型,则此方法返回的值一定是相应基本包装对象类的实例;否则,它一定是可分配到声明返回类型的类型。如果此方法返回的值为 null 并且接口方法的返回类型是基本类型,则代理实例上的方法调用将抛出 NullPointerException。否则,如果此方法返回的值与上述接口方法的声明返回类型不兼容,则代理实例上的方法调用将抛出 ClassCastException



你可能感兴趣的:(java基础)