zoukankan      html  css  js  c++  java
  • 一文撸明白 静态代理和动态代理

    先直接上代码干货

    创建一个Speak接口和ZhangSan实体类

    Speaker接口:
    public interface Speaker {
        void speak();
    }
    
    ZhangSan类:
    public class ZhangSan implements Speaker {
        @Override
        public void speak() {
            System.out.println("张三: 哈哈哈哈哈");
        }
    }

    这个时候,如果我们需要ZhangSan在speak之前或者之后干点啥,,,就需要使用代理类来增强目标类实现

    1.采用静态代理类实现

    ZhangSan代理类(增强类):
    public class ZhangSanProxyer implements Speaker {
        //注入ZhangSan对象
        private ZhangSan zs = new ZhangSan();
    
        @Override
        public void speak() {
            System.out.println("嘻嘻嘻嘻");
            zs.speak();
            System.out.println("呵呵呵呵");
        }
    }

    此时,通过如下代码调用,即可实现增强

    //静态代理
    Speaker speaker = new ZhangSanProxyer();
    speaker.speak();

     2.采用 jdk动态代理实现

    创建一个代理抽象层:
    public class Proxyer implements InvocationHandler {
    
        private Object obj;
    
        public Proxyer(Object obj) {
            this.obj = obj;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if ("speak".equals(method.getName())){
                System.out.println("嘻嘻嘻嘻");
                method.invoke(obj,args);
                System.out.println("呵呵呵呵");
            }
    
            return null;
        }
    }

    此时,通过如下代码调用,即可实现增强

    //jdk动态代理
    Proxyer proxyer = new Proxyer(new ZhangSan());
    Speaker speaker1 = (Speaker) Proxy.newProxyInstance(Demo.class.getClassLoader(),new Class[]{Speaker.class},proxyer);
    speaker1.speak();

    3.采用 cglib动态代理实现

    创建Lisi实体类(不实现接口):
    public class Lisi {
        public void speak() {
            System.out.println("李四: 哈哈哈哈哈");
        }
    }
    
    创建代理增强类实现增强:
    public class Interceptor implements MethodInterceptor {
    
        private Object obj;
    
        public Interceptor(Object obj) {
            this.obj = obj;
        }
    
        @Override
        public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            if ("speak".equals(method.getName())){
                System.out.println("嘻嘻嘻嘻");
                method.invoke(obj,args);
                System.out.println("呵呵呵呵");
            }
    
            return null;
        }
    }

    此时,通过如下代码调用,即可实现增强

    //cglib动态代理
    Interceptor interceptor = new Interceptor(new Lisi());
    Lisi lisi = (Lisi) Enhancer.create(Lisi.class, interceptor);
    lisi.speak();

    总结:

    代理模式:

    代理模式可以在不修改被代理对象的基础上,通过扩展代理类,进行一些功能的附加与增强。值得注意的是,代理类和被代理类应该共同实现一个接口,或者是共同继承某个类。

    静态代理和动态代理,都是基于代理模式实现的一种对于类的方法的增强。

     静态代理:

    所谓静态代理,其实就是在编译期完成代理(程序运行前就已经存在代理类的字节码文件)

    动态代理:

    动态代理是利用反射机制在运行时创建代理类, 其实是对代理类做了进一步抽象和封装,提高其复用性

    jdk动态代理:

    两个核心对象:
    invocationHandler接口, Proxy类

    1.被代理类需要实现某个接口(自己定义的接口也可以)。
    2.实现invocationHandler接口的类作为代理类的参数,invocationHandler接口有一个invoke抽象方法需要实现
    3.使用jdk中的Proxy类的静态方法newProxyInstance()方法,生成一个代理类

    cglib动态代理:

    两个核心对象:
    MethodInterceptor接口 ,Enhancer类

    1.被代理类没有实现接口
    2.创建自己的方法拦截处理器Interceptor 实现 MethodInterceptor 接口, 接口中有一个intercept方法需要实现
    3.使用Enhancer.create方法创建代理增强类
  • 相关阅读:
    PAT-乙级-1008 数组元素循环右移问题
    PAT-乙级-1007 素数对猜想
    PAT-乙级-1006 换个格式输出整数
    PAT-乙级-1005 继续(3n+1)猜想
    PAT-乙级-1003 我要通过!
    PAT-乙级-1004 成绩排名
    PAT-乙级-1002 写出这个数
    PAT-乙级-1001 害死人不偿命的(3n+1)猜想
    PAT-甲级-1002-A+B for Polynomials
    【windows】共享文件夹设置
  • 原文地址:https://www.cnblogs.com/Baker-Street/p/15033543.html
Copyright © 2011-2022 走看看