• 如何实现使用原生的Java API实现代理模式_java培训


    使用原生的Java API实现代理模式

    ① 情景举例

    [1] 声明计算器接口

    public interface Calculator {
        void add(int a, int b);

        void sub(int a, int b);

        void mul(int a, int b);

        void div(int a, int b);
    }

    [2] 创建计算器接口实现类

    public class CalculatorImpl implements Calculator {
        @Override
        public void add(int a, int b) {
            System.out.println(“(a + b) = ” + (a + b));
        }

        @Override
        public void sub(int a, int b) {
            System.out.println(“(a – b) = ” + (a – b));
        }

        @Override
        public void mul(int a, int b) {
            System.out.println(“(a × b) = ” + (a * b));
        }

        @Override
        public void div(int a, int b) {
            System.out.println(“(a ÷ b) = ” + (a / b));
        }
    }

    ② 静态代理

    局部来看确实实现了代理模式的要求,但是所有代码都是写死的,日志这样的通用功能的代码无法重用,没有任何的灵活性。

    public class StaticProxyCalculator implements Calculator {

        private Calculator calculator;
        public StaticProxyCalculator(Calculator calculator) {
            this.calculator = calculator;
        }

        @Override
        public void add(int a, int b) {
            System.out.println(“[debug][static proxy]add method begin”);
            this.calculator.add(a, b);
            System.out.println(“[debug][static proxy]add method end”);
        }

        @Override
        public void sub(int a, int b) {
            System.out.println(“[debug][static proxy]sub method begin”);
            this.calculator.sub(a, b);
            System.out.println(“[debug][static proxy]sub method end”);
        }

        @Override
        public void mul(int a, int b) {
            System.out.println(“[debug][static proxy]mul method begin”);
            this.calculator.mul(a, b);
            System.out.println(“[debug][static proxy]mul method end”);
        }

        @Override
        public void div(int a, int b) {
            System.out.println(“[debug][static proxy]div method begin”);

            this.calculator.div(a, b);
            System.out.println(“[debug][static proxy]div method end”);
        }
    }

    ③ 动态代理

    /**
     * 专门抽取日志打印功能的动态代理类
     */
    public class DynamicLogProxy {

        // 被代理的目标对象
        private Object target;

        // 通过构造器接收被代理的目标对象
        public DynamicLogProxy(Object target) {
            this.target = target;
        }

        public Object getProxy() {
            return Proxy.newProxyInstance(

                    // 目标对象的类加载器
                    this.target.getClass().getClassLoader(),
                    // 目标对象实现的所有接口(既然代理对象是为target对象做代理,那么就应该和target对象一样实现target对象的所有接口
                    this.target.getClass().getInterfaces(),

                    // InvocationHandler对象
                    (Object proxy, Method method, Object[] args)->{
                        // 获取被代理的目标方法的方法名
                        String methodName = method.getName();
                        Object returnValue = null;
                        try {
                            // 方法开始执行前位置
                            System.out.println(“[Log]Method ” + methodName + ” begin.”);
                            // 通过反射调用目标方法
                            returnValue = method.invoke(target, args);
                            // 方法正常结束位置(寿终正寝)
                            System.out.println(“[Log]Method ” + methodName + ” ended successfully.”);

                        } catch (Exception e) {
                            String exceptionName = e.getClass().getName();
                            while (e.getCause() != null) {
                                exceptionName = e.getCause().getClass().getName();
                                e = (Exception) e.getCause();
                            }
                            // 方法异常结束位置(死于非命)
                            System.out.println(“[Log]Method ” + methodName + ” ended with exception: “+ exceptionName +”.”);

                        } finally {

                            // 方法最终结束位置(盖棺定论)
                            System.out.println(“[Log]Method ” + methodName + ” finally ended.”);
                        }
                        return returnValue;
            });
        }
    }

    junit测试:

    @Test
    public void testDynamicLogProxy() {

        // 1.创建被代理对象
        Calculator target = new CalculatorImpl();

        // 2.创建代理对象
        DynamicLogProxy proxy = new DynamicLogProxy(target);
        Calculator calculator = (Calculator) proxy.getProxy();

        // 3.通过代理对象调用业务方法
        calculator.add(3, 5);
        calculator.sub(6, 2);
        calculator.mul(4, 7);
        calculator.div(3, 0);
    }

    想要了解跟多关于java培训课程内容欢迎关注尚硅谷java培训,尚硅谷除了这些技术文章外还有免费的高质量java培训课程视频供广大学员下载学习。

  • 相关阅读:
    11月了,焦虑烦躁,然后是无悲无喜
    Docker 安装 Nginx 容器 (完整详细版)
    Mysql密码忘记后怎么重置密码,mysql8之后有改动
    图像处理 QImage
    入侵检测系统
    SpringBoot的SSMP案例(后端开发)
    linux 进程管理命令
    selenium元素定位---ElementClickInterceptedException(元素点击交互异常)解决方法
    公司如何防止源代码外泄,保护开发部门代码安全呢?
    设计模式:命令模式(C++实现)
  • 原文地址:https://blog.csdn.net/zjjcchina/article/details/126657386