浅谈java代理类proxy
发布日期:2021-10-02 10:57:01 浏览次数:30 分类:技术文章

本文共 3034 字,大约阅读时间需要 10 分钟。

代理类的作用,顾名思义,代理类,是类的代理,将类给代理,不直接调用类的方法,而通过代理来调用。
构造方法:
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.Integer
java.lang.Boolean)的实例中。
返回:
从代理实例的方法调用返回的值。如果接口方法的声明返回类型是基本类型,则此方法返回的值一定是相应基本包装对象类的实例;否则,它一定是可分配到声明返回类型的类型。如果此方法返回的值为
null 并且接口方法的返回类型是基本类型,则代理实例上的方法调用将抛出
NullPointerException。否则,如果此方法返回的值与上述接口方法的声明返回类型不兼容,则代理实例上的方法调用将抛出
ClassCastException

转载地址:https://blog.csdn.net/jiangyunlovec/article/details/53413516 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:mysql常用sql
下一篇:Linux进程的组成部分

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.219.124.196]2024年04月11日 19时17分31秒