• 《设计模式之禅》--代理扩展:动态代理


    接上篇《设计模式之禅》--代理扩展:强制代理

    动态代理就是在实现阶段不用关心代理谁,而在运行阶段才指定代理哪一个对象。相对来说,自己写代理类的方式就是静态代理

    面向切面编程(AOP)核心就是采用了动态代理机制

    public interface Subject {
        //业务操作
        public void doSomething(String str);
    }
    public class RealSubject implements Subject {
        //业务操作
        public void doSomething(String str) {
            System.out.println("do something!---->" + str);
        }
    }
    public class MyInvocationHandler implements InvocationHandler {
        //被代理的对象
        private Object target = null;
    
        //通过构造函数传递一个对象
        public MyInvocationHandler(Object _obj) {
            this.target = _obj;
        }
    
        //代理方法
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            //执行被代理的方法
            return method.invoke(this.target, args);
        }
    }
    public class DynamicProxy<T> {
        public static <T> T newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) {
            //寻找JoinPoint连接点,AOP框架使用元数据定义
            if (true) {
                //执行一个前置通知
                (new BeforeAdvice()).exec();
            }
            //执行目标,并返回结果
            return (T) Proxy.newProxyInstance(loader, interfaces, h);
        }
    }
    public interface IAdvice {
        //通知只有一个方法,执行即可
        public void exec();
    }
    
    public class BeforeAdvice implements IAdvice {
        public void exec() {
            System.out.println("我是前置通知,我被执行了!");
        }
    }

    调用

    public class Client {
        public static void main(String[] args) {
            //定义一个主题
            Subject subject = new RealSubject();
            //定义一个Handler
            InvocationHandler handler = new MyInvocationHandler(subject);
            //定义主题的代理
            Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().
                    getClassLoader(), subject.getClass().getInterfaces(), handler);
            //代理的行为
            proxy.doSomething("Finish");
        }
    }

    结果

    我是前置通知,我被执行了!
    do something!---->Finish

    拓展:

    public class SubjectDynamicProxy extends DynamicProxy {
        public static <T> T newProxyInstance(Subject subject) {
            //获得ClassLoader
            ClassLoader loader = subject.getClass().getClassLoader();
            //获得接口数组
            Class<?>[] classes = subject.getClass().getInterfaces();
            //获得handler
            InvocationHandler handler = new MyInvocationHandler(subject);
            return newProxyInstance(loader, classes, handler);
        }
    }

     调用

    public class Client {
        public static void main(String[] args) {
            //定义一个主题
            Subject subject = new RealSubject();
            //定义主题的代理
            Subject proxy = SubjectDynamicProxy.newProxyInstance(subject);
            //代理的行为
            proxy.doSomething("Finish");
        }
    }
  • 相关阅读:
    [BFS]luogu P2536 [AHOI2005]病毒检测
    AtCoder Regular Contest 116 总结
    NOI online 2021 #1 总结
    博客半复活
    vue2 Bus兄弟组件间传值问题:重复触发和首次未触发
    ant design中table组件的filter,如何在外部控制
    ant design vue 日期排序
    什么是断点续传?前端如何实现文件的断点续传
    主vue前端面试题补充
    P4248 [AHOI2013]差异 题解
  • 原文地址:https://www.cnblogs.com/anni-qianqian/p/8436214.html
Copyright © 2020-2023  润新知