博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java动态代理-JDK自带实现
阅读量:4345 次
发布时间:2019-06-07

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

       上篇文章讲解了什么是静态代理,但是静态代理有一个问题就是需要建立很多的代理类,这样我们需要修改代理的方法的时候,需要在每个类中都要修改,这对于我们来说:当代理类很多的时候工作量就会成倍的增加。

       于是针对上述问题,人们就提出了解决方案,我们在运行中来实现代理类的创建,也就是今天要讲解的主题——动态代理,首先先说的是JDK自带的动态代理的实现。

         JDK自带的代理实现中最重要的两个内容:一是Proxy类,另一个是InvocationHandler接口。这两个是实现动态代理必须要用到的类和接口。

         1)对于InvocationHandler接口,API给出了这样的定义:           

     InvocationHandler 是代理实例的调用处理程序 实现的接口。

                每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,

                将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法

               

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

                   proxy:指代理的那个真实对象

 

                   method:指调用真是对象的某个方法Method对象

                   args:指调用真实对象某个方法时接受的参数

          2)Proxy类:

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

               

public static Object newProxyInstance(ClassLoader loader,                                      Class
[] interfaces, InvocationHandler h) throws IllegalArgumentException

               loader:定义代理类的类加载器

 

               interface:代理类要实现的接口列表

               h:指派方法调用处理程序

               返回值:一个带有代理类的指定调用处理程序的代理实例,它由指定的类加载器定义,并实现指定的接口

                               也就是(返回一个由类加载器指定的代理类,它具有代理类Proxy中方法)这是我个人的理解

           以上已经对于JDK中用到的内容进行了简单的了解,接下来我们来看如何在代码中实现动态代理,

1、定义一个接口

    

public interface Hello {    void say(String name);}

2、定义一个类来实现这个接口,这个类就是我们的真实对象,HelloImpl

 

public class HelloImpl implements Hello {    @Override    public void say(String name) {        System.out.println("Hello!"+name);    }}

3、定义一个动态代理,每个动态代理类都必须实现InvocationHandler这个接口

public class DynamicProxy implements InvocationHandler {    private Object target;    public DynamicProxy(Object target){        this.target=target;    }    @SuppressWarnings("unchecked")    public 
T getProxy(){ return (T) Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), this ); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { before(); Object result =method.invoke(target,args); after(); return result; } private void before(){ System.out.println("Before"); } private void after(){ System.out.println("After"); }}

4、接下来就是在客户端调用

public class Test {       public static void main(String[] args){        Hello hello =new HelloImpl();        DynamicProxy dynamicProxy = new DynamicProxy(hello);        Hello helloProxy=(Hello) Proxy.newProxyInstance(                hello.getClass().getClassLoader(),                hello.getClass().getInterfaces(),                dynamicProxy        );        helloProxy.say("Jack");            }}

问题:由于上述在客户端调用过程中,每次动态创建代理类都会使用newProxyInstance这个方法,我们对其进行一层封装,如下:

1、封装一个类,HelloProxy

public class HelloProxy implements Hello {    private  Hello hello;    public HelloProxy(){        hello=new HelloImpl();    }    @Override    public void say(String name) {        before();        hello.say(name);        after();    }    private void before(){        System.out.println("Before");    }    private void after(){        System.out.println("After");    }}

2、客户端调用

public class Test {       public static void main(String[] args){                DynamicProxy dynamicProxy=new DynamicProxy(new HelloImpl());        Hello helloProxy =dynamicProxy.getProxy();        helloProxy.say("Jack");            }}

转载于:https://www.cnblogs.com/zsswpb/p/6329423.html

你可能感兴趣的文章
关于SQL的相关笔记【长期更新,只发一帖】
查看>>
linux awk命令详解
查看>>
android:id="@+id/button1" 与 android:id="@id/button1" 区别 @string
查看>>
手把手玩转win8开发系列课程(11)
查看>>
Linux Namespace : User
查看>>
交换两个整形变量的数值
查看>>
Linux----常用操作
查看>>
sequence
查看>>
Delphi错误:Stack overflow的解决方法
查看>>
取消chrome(谷歌浏览器)浏览器下最小字体限制
查看>>
模板方法模式
查看>>
什么是ECC内存?
查看>>
使用Visual Studio 2013进行UI自动化测试
查看>>
13-集体照
查看>>
读了曾国藩家书,,心态逐渐平和起来。搞技术的如果缺乏信念的指引,生活会很乏味无聊!...
查看>>
前端javascript 错误 Uncaught SyntaxError: Unexpected token ILLEGAL
查看>>
Selenium WebDriver问题--无法打开Chrome浏览器
查看>>
2017.4.18 Java的Integer与int互转
查看>>
小程序接受返回数组的坑
查看>>
echart.js的使用
查看>>