动态代理Dynamic Proxy

Posted xjs1874704478

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态代理Dynamic Proxy相关的知识,希望对你有一定的参考价值。

技术图片

  代理模式是常用的Java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类

预处理消息,过滤消息,把消息转发给委托类,以及事后处理消息等。

  代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身

并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定服务。

 

动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。

Java反射机制可以生成任意类型的动态代理类。java.lang.reflect包中的Proxy类和invocationHandler接口提供了

生成动态代理类的能力。

InvocationHandler接口:

public interface InvocationHandler{

  public Object invoke(Object proxy,Method method, Object[] args)throws Throwable;

  //  返回值null      1.指被代理的对象2.要调用的方法3.方法调用时所需要的参数

}

 

Proxy类:

是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类,此类提供了(静态方法)如下的操作方法:

public sattic Object newProxyInstance(ClassLoader  loader,Class<?>[]  interfaces,  InvocationHandler  h)throws IllegalArgumentException

参数说明:ClassLoader  loader:类加载器

     Class<?>[]  interfaces: 得到全部的接口

     InvocationHandler  h:得到InvocationHandler接口的子类实例

 

类对象.getClass.getClassLoader();---获得类加载器

 


举例:一个吃饭的例子,我们只管吃饭,把饭前洗手,饭后刷碗的重复事情交给代理类来完成

Dinner.java-----接口

1 package Jun.Proxy;
2 
3 public interface Dinner {
4     public String haveDinner();
5 }

MyDinner.java------自己的实现类-------委托类

 1 package Jun.Proxy;
 2 
 3 public class MyDinner implements Dinner{
 4 
 5     @Override
 6     public String haveDinner() {
 7         System.out.println("妈妈做的饭真好吃。。。。。");
 8         return "真得好吃====";
 9     }
10 
11 }

MyDinnerProxy.java--------代理类

功能就是,给它一个委托类对象,会返回一个代理类对象,使用的是Proxy类的方法

Proxy.newProxyInstance----得到代理类对象(实例)

 1 package Jun.Proxy;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 import java.lang.reflect.Proxy;
 6 
 7 public class MyDinnerProxy implements InvocationHandler{
 8 
 9     private Object originalObject;//被代理的原始对象
10     
11     //绑定原始对象,返回一个代理对象
12     public Object bind(Object obj) {
13         this.originalObject=obj;
14         //里面的参数1:类加载器2:得到全部的接口3:得到InvocationHandler接口的实例---当前对象本身实现的这个接口
15         return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
16     }
17     
18     //吃饭之前要执行的方法
19     private void preMethod() {
20         System.out.println("吃饭之前要洗手。。。");
21     }
22     //吃饭之后要执行的方法
23     private void afterMethod() {
24         System.out.println("吃饭之后要刷碗。。。。");
25     }
26     @Override
27     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
28         preMethod();
29         Object result=method.invoke(this.originalObject, args);
30         afterMethod();
31         //invoke方法返回一个对象
32         System.out.println("hahahahahhaha----"+result);
33         return result;
34     }    
35 }

 

MyDinnerProxyDemo.java-----测试

 1 package Jun.Proxy;
 2 
 3 public class MyDinnerProxyDemo {
 4 
 5     public static void main(String[] args) {
 6         Dinner din=new MyDinner();
 7 //        din.haveDinner();
 8         //代理类的实列
 9         MyDinnerProxy pro=new MyDinnerProxy();
10         //返回了一个代理对象
11         din=(Dinner) pro.bind(din);
12         String str=din.haveDinner();
13         System.out.println("----------------------");
14         System.out.println(str);
15     }
16 }

 

以上是关于动态代理Dynamic Proxy的主要内容,如果未能解决你的问题,请参考以下文章

动态代理Dynamic Proxy

跟王老师学反射:动态代理

JDK动态代理源码分析

转JDK动态代理原理

spring动态代理

Castle Dynamic Proxy IInvocation 在 .net Core 和 Framework 中真的不同吗?