• java动态代理详解


    记录学习的每一点过程

    本文主要介绍的是动态代理,所以静态代理在这里就简单介绍一下

    1、静态代理

    静态代理的角色介绍

    抽象角色:一般是接口或者是抽象类

    1 /**
    2  * 抽象角色:以租房为例,这是一个租房子的接口
    3  */
    4 public interface Rent {
    5     void rent();
    6 }

    真实角色:被代理的角色

     1 /**
     2  * 文件名:Host
     3  * 作 者:zyz
     4  * 时 间:2019/6/12 9:47
     5  * -------------------------
     6  * 功能和描述:真实角色,实现抽象角色对应的接口(Rent)
     7  **/
     8 public class Host implements Rent{
     9     public void rent(){
    10         System.out.println("房屋出租");
    11     }
    12 }

    代理角色:代理真实角色,代理真实角色之后,一般会做一些附属(增强的操作)

    
    
     1 /**
     2  * 代理角色:同真实角色实现同一个接口
     3  */
     4 public class Proxy implements Rent {
     5     private Host host;
     6 
     7     public Proxy() {
     8     }
     9 
    10     public Proxy(Host host) {
    11         this.host = host;
    12     }
    13 
    14     public void setHost(Host host) {
    15         this.host = host;
    16     }
    17 
    18     public void rent() {
    19         seeHouse();
    20         host.rent();
    21         fee();
    22     }
    23 
    24 
    25     //**************代理角色附带(增强)的一些功能**************//
    26     private void seeHouse(){
    27         System.out.println("带租客看房子");
    28     }
    29     private void fee(){
    30         System.out.println("收取中介费");
    31     }
    32 }
    
    
    

    测试类
     
     1 /**
     2  * 文件名:Client
     3  * 作 者:zyz
     4  * 时 间:2019/6/12 9:47
     5  * -------------------------
     6  * 功能和描述:
     7  **/
     8 
     9 public class Client {
    10     public static void main(String[] args) {
    11         //定义一个真实角色
    12         Host host = new Host();
    13         //定义代理角色
    14         Proxy proxy = new Proxy(host);
    15         //使用代理角色的实例去实现具体操作
    16         proxy.rent();
    17     }
    18 }

     静态代理总结

      优点:

        使真实角色处理的业务更加的纯粹,不再关注一些公共的事;

        公共的业务由代理来完成,实现了业务的分工;

        公共业务的扩展变得更加集中和方便

      缺点:

        类变多了,多了代理类,工作量变大了,且不易扩展

        解决此问题的方案就是使用动态代理

    2、动态代理

     还是以租房子为例,因为在学习阶段,越是简单的例子越是容易理解,博主在学习的时候看到了好几篇文章光看代码就晕头转向的了,还没学习动态代理就已经蒙了。所以我这边举得例子基本都是大家常见的,代码简单,但是能将知识点介绍的很透彻。

    动态代理有两种实现方式:一种是基于jdk的动态代理,一种是基于cglib的动态代理

    基于jdk的动态代理

    基于jdk的动态代理的特点是必须要有接口,记住一个类Proxy(java.lang.reflect.Proxy,别导错包)和一个接口InvocationHandler,废话少说,直接上代码

     第一步:新建一个接口Rent

    
    
    1 public interface Rent {
    2     void rent();
    3 }
    
    

    第二步:新建一个类(Host),实现该接口(Rent)
    
    
    1 public class Host implements Rent{
    2     public void rent(){
    3         System.out.println("房屋出租");
    4     }
    5 }
    
    

    第三步:新建一个代理类,实现
    InvocationHandler接口
    
    
     1 public class RentInvocationHandler implements InvocationHandler {
     2 
     3     private Object object;
     4 
     5     public  RentInvocationHandler(Object object) {
     6         this.object = object;
     7     }
     8 
     9     /**
    10      * @param proxy:代理类
    11      * @param method:代理类调用处理程序的方法对象
    12      * @param args:方法的参数
    13      */
    14     @Override
    15     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    16         System.out.println("使用动态代理做的一些增强的操作......");
    17         //第一个参数表示真实对象
    18         //第二个参数表示参数
    19         Object result = method.invoke(object, args);
    20 
    21         return result;
    22     }
    23 }
    
    
    

    完工就是这么easy,下面开始测试
    
    
     1 public class Client {
     2     public static void main(String[] args) {
     3         //定义一个真实对象
     4         Host host = new Host();
     5         //创建代理类
     6         RentInvocationHandler pih = new RentInvocationHandler(host);
     7         //利用Proxy.newProxyInstance生成代理类
     8         //第一个参数:真实类对象的类加载器
     9         //第二个参数:真实类对象的所有的接口
    10         //第三个参数:代理类对象
    11         Rent p = (Rent)Proxy.newProxyInstance(host.getClass().getClassLoader(),host.getClass().getInterfaces(),pih);
    12         p.rent();
    13 
    14     }
    15 }
    
    
    

    输出:

    再次强调一点:在调用的时候
    Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
    

      只要搞清楚这里面的三个参数是干嘛的就OK


    基于CGLib的动态代理

      基于CGLib的动态代理是没有接口的限制的,行了,直接撸代码(虽然有重复的代码,但是为了让读者能够看的清晰,每一步我都会写出来)

     第一步:创建一类真实类Host_CGLib 

      <dependency>

            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2.2</version>
    </dependency> 
    1 public class Host_CGLib {
    2     public void rent(){
    3         System.out.println("租房子......CGLib");
    4     }
    5   }
    
    

    第二步:创建一个拦截器类实现MethodInterceptor(
    net.sf.cglib.proxy.MethodInterceptor)接口
    1 public class RentMethodInterceptor implements MethodInterceptor {
    2     @Override
    3     public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    4         System.out.println("使用CGLib方式做的增强......");
    5         Object result = methodProxy.invokeSuper(o, objects);
    6         return result;
    7     }
    8 }
    OK搞定,开始测试
     1 public class CGLibTest {
     2     public static void main(String[] args) {
     3         //设置增强需要用到的类
     4         Enhancer enhancer = new Enhancer();
     5         //设置需要增强的类(这里是Host_CGLib类)
     6         enhancer.setSuperclass(Host_CGLib.class);
     7         //设置需要回调的拦截器
     8         enhancer.setCallback(new RentMethodInterceptor());
     9         //生成对应的增强类
    10         Host_CGLib host = (Host_CGLib)enhancer.create();
    11         host.rent();
    12     }
    13 }
    输出:
    总结:对于底层和原理这边并没有介绍,至于为什么没有介绍(因为我也不会),因为初学者先知道怎么用就行,不是什么东西都是刨根问底的,现在知道是什么,再是搞为什么吧。熟悉了以后在此基础上去深挖,这才是王道。
    
    如果您觉得我写的文章您看明白了,请动动您的小手,将文章分享给您的好友哦!

      

     
     
     
  • 相关阅读:
    You are not late! You are not early!
    在同一个服务器(同一个IP)为不同域名绑定的免费SSL证书
    Vue.js Is Good, but Is It Better Than Angular or React?
    It was not possible to find any compatible framework version
    VS增加插件 Supercharger破解教程
    Git使用ssh key
    Disconnected: No supported authentication methods available (server sent: publickey)
    VS 2013打开.edmx文件时报类型转换异常
    asp.net MVC4 框架揭秘 读书笔记系列3
    asp.net MVC4 框架揭秘 读书笔记系列2
  • 原文地址:https://www.cnblogs.com/zyzblogs/p/11009872.html
Copyright © 2020-2023  润新知