• 设计模式-代理模式


    代理模式

    应用场景:不该变源代码,给源代码增加功能。

    在Java中,常用的代理有JDK动态代理和cglib动态代理。JDK动态代理由java.lang.reflect包下的Proxy提供的,基于接口生成的代理类,实现对目标类的代理;cglib是由Oracle提供的Java开发工具包,采用字节码技术,直接修改字节码并生成代理子类。
    注意:JDK动态代理中,调用方法时其代理类并不知道目标类的具体方法,因此需要通过反射来进行调用,效率很低。

    JDK实现动态代理

    public class Person implements IPerson {
        @Override
        public void eat(){
            System.out.println("开始吃饭");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    1.定义接口,定义需要代理的方法

    public interface IPerson {
        public void eat();
    }
    
    • 1
    • 2
    • 3

    2.定义类并创建代理对象

        public static IPerson createPersonProxy(Person person){
            IPerson iPersonProxy = (IPerson) Proxy.newProxyInstance(PersonProxy.class.getClassLoader()
                    , new Class[]{IPerson.class}
                    , new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            if(method.getName() == "eat"){
                                System.out.println("拿筷子");
                                System.out.println("拿碗");
                            }
    
                            return method.invoke(person ,args);
                        }
                    });
            return iPersonProxy;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    3.调用代理对象的方法

    public class Demo {
        public static void main(String[] args) {
            Person person = new Person();
            IPerson personProxy = PersonProxy.createPersonProxy(person);
            personProxy.eat();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    CGLIB实现动态代理

    public class Person{
        public void eat(){
            System.out.println("开始吃饭");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    public class PersonProxy implements MethodInterceptor {
        private Enhancer enhancer = new Enhancer();
    
        public Object getProxy(Class clazz){
            enhancer.setSuperclass(clazz);
            enhancer.setCallback(this);
            //通过字节码技术动态创建子类实例
            return enhancer.create();
        }
    
        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            if(method.getName().equals("eat")){
                System.out.println("拿筷子");
                System.out.println("拿碗");
            }
    
            //通过代理类调用父类中的方法
            Object result = methodProxy.invokeSuper(o, objects);
    
            return result;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
  • 相关阅读:
    面试算法之递归和循环
    区块链学姐:8月9日以太持续破新高,空头能量是否还存在?
    10.3 调试事件转存进程内存
    ADS-B及雷达显示终端8.3
    c# sqlsugar,hisql,freesql orm框架全方位性能测试对比 sqlserver 性能测试
    【数学建模】2023数学建模国赛C题完整思路和代码解析
    Gradio Dataframe 学习笔记
    go语言中的数组指针和指针数组的区别详解
    【车载开发系列】UDS诊断---电控单元复位 ($0x11)
    PMP的最新发展趋势?你可知?
  • 原文地址:https://blog.csdn.net/qq_52763385/article/details/132752408