美文网首页
8 代理设计模式

8 代理设计模式

作者: 滔滔逐浪 | 来源:发表于2022-07-03 21:59 被阅读0次

    代理模式是主要对我们方法执行之前与之后实现增强。
    代理模式应用场景
    1,日志采集
    2,权限控制
    3,实现aop
    4,mybatis mapper
    5,Spring的事务
    6,全局捕获异常
    7,rpc远程调用接口(传递就是接口)
    8,代理数据源
    9,自定义注解
    aop---基于代理实现
    代理模式实现的原理
    代理模式主要包含三个角色,即抽象主题角色(Subject),委托类角色(被代理角色,Proxied)以及代理类角色(Proxy)
    抽象主题角色:可以是接口,也可以是抽象类;
    委托类角色: 真实主题角色,业务逻辑的具体执行者;
    代理类角色: 内部含有对真实对象RealSubject的引用,负责对真实主题角色的调用,并在真实主题角色处理前后做预处理和后处理。
    代理模式创建方式:
    相关测试代码:

    package com.taotao.proxy.service;
    
    /**
     * @Author: wangjin
     * @CreateTime: 2022-07-03  21:23
     */
    public interface OrderService {
        /**
         * 追加订单数据
         */
        String addOrder(String orderName);
    }
    
    
    
    package com.taotao.proxy.service.impl;
    
    import com.taotao.proxy.service.OrderService;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Service;
    
    /**
     * @Author: wangjin
     * @CreateTime: 2022-07-03  21:24
     */
    @Service("OrderService")
    @Slf4j
    public class OrderServiceImpl implements OrderService {
        @Override
        public String addOrder(String orderName) {
    
            log.info("<orderName:{}>", orderName);
            log.info("addOrder方法之后处理");
            return "OK";
        }
    }
    
    
    
    package com.taotao.proxy.service.proxy;
    
    import com.taotao.proxy.service.OrderService;
    import lombok.extern.slf4j.Slf4j;
    
    /**
     * @Author: wangjin
     * @CreateTime: 2022-07-03  21:37
     */
    @Slf4j
    public class OrderServiceProxy implements OrderService {
        //代理类 到底是需要调用哪一个 被代理类
        private OrderService orderService;
    
        public OrderServiceProxy(OrderService orderService) {
            this.orderService = orderService;
        }
    
        @Override
        public String addOrder(String orderName) {
            log.info("<在adder方法之前处理 orderName:{}>", orderName);
            String resultString = orderService.addOrder(orderName);//调用被代理类
            return resultString;
        }
    }
    
    
    package com.taotao.proxy.service;
    
    import com.taotao.proxy.service.impl.OrderServiceImpl;
    import com.taotao.proxy.service.proxy.OrderServiceProxy;
    
    /**
     * @Author: wangjin
     * @CreateTime: 2022-07-03  21:44
     */
    public class Test01 {
        public static void main(String[] args) {
            //被代理类
            OrderServiceProxy orderServiceProxy=new OrderServiceProxy(new OrderServiceImpl());
            String result= orderServiceProxy.addOrder("hello");
            System.out.println(result);
        }
    }
    
    
    
    package com.taotao.proxy.service;
    
    import com.taotao.proxy.service.proxy1.OrderServiceProxy;
    
    /**
     * @Author: wangjin
     * @CreateTime: 2022-07-03  21:56
     */
    public class Test02 {
        public static void main(String[] args) {
            OrderServiceProxy orderServiceProxy=new OrderServiceProxy();
          String result=  orderServiceProxy.addOrder("oooo");
            System.out.println(result);
        }
    }
    
    
    
    package com.taotao.proxy.service.proxy1;
    
    import com.taotao.proxy.service.impl.OrderServiceImpl;
    import lombok.extern.slf4j.Slf4j;
    
    /**
     * @Author: wangjin
     * @CreateTime: 2022-07-03  21:51
     */
    @Slf4j
    public class OrderServiceProxy  extends OrderServiceImpl {
        //让我们代理类 继承 代理类
    
        @Override
        public String addOrder(String orderName) {
            log.info("<在addOrder方法之前处理 orderName:{}>",orderName);
            String result=super.addOrder(orderName);
             //目标方法 执行 被代理类
            log.info("<在addOrder方法之后处理 orderName:{}>",orderName);
            return result;
        }
    }
    
    

    动态代理是在实现阶段不用关心代理类,而是在运行阶段才指定哪一个对象。
    动态代理类的源码是在程序运行期间由JVM根据反射等机制动态生成。
    jdk动态代理的一般步骤如下:
    1,创建被代理的接口和类
    2,实现InvocationHandler接口,对目标接口中声明的所有方法进行统一处理;
    3,调用Proxy的静态方法,创建代理类并生成相应的代理对象;
    实现原理: 利用拦截器机制必须实现InvocationHandler 接口中的invoke方法实现对我们的目标方法增强

    JDK API 动态代理方法:

    package com.taotao.proxy.service;
    
    import lombok.extern.slf4j.Slf4j;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    /**
     * @Author: wangjin
     * @CreateTime: 2022-07-03  22:36
     */
    @Slf4j
    public class JdkInvocationHandler implements InvocationHandler {
        /**
         * 目标对象
         */
        private Object target;
        public JdkInvocationHandler(Object target){
            this.target=target;
        }
        /**
         *
         * @param proxy jdk自动生成好的代理类
         * @param method 木目标对象的接口
         * @param args 参数类
         * @return
         * @throws Throwable
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
          log.info("<jdk动态代理目标方法之前>,args:{}",args);
          Object result=method.invoke(target,args);
            log.info("<jdk动态代理目标方法之后,args:{}", args);
            return result;
        }
        public <T> T getProxy() {
            return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
        }
    }
    
    
    
    
    
    
    package com.taotao;
    
    import com.taotao.proxy.service.JdkInvocationHandler;
    import com.taotao.proxy.service.OrderService;
    import com.taotao.proxy.service.impl.OrderServiceImpl;
    
    /**
     * @Author: wangjin
     * @CreateTime: 2022-07-05  22:25
     */
    public class Test03 {
        public static void main(String[] args) {
            OrderService orderService=new JdkInvocationHandler(new OrderServiceImpl()).getProxy();
               orderService.addOrder("taotao");
        }
    }
    
    

    动态代理与静态代理的区别
    动态代理不需要写代理类对象,通过程序自动生成,而静态代理需要我们自己写代理类对象。

    相关文章

      网友评论

          本文标题:8 代理设计模式

          本文链接:https://www.haomeiwen.com/subject/thjrbrtx.html