zoukankan      html  css  js  c++  java
  • 【面试】:阿里面试官问我设计模式——代理模式,我是这样回答的!

    1.什么是代理模式? 为对象提供一种代理以控制对这个对象的访问。代理模式相当于:中介或者经纪人 ,代理类可以在被代理类的基础之上增加功能(扩展功能),比如日志记录和权限控制 ,这样被代理类隐藏起来了,比较安全。

    1.代理模式实现方式有哪些?
    静态代理和动态代理
    2.静态代理是:需要程序员人为创建好代理类,缺点;如果被代理类很多的话,需要手写很多个代理类,代码会变得非常冗余。
    3.静态代理实现方式有哪些?
    1.通过继承2.实现接口

    1.通过实现接口方式实现静态代理

    1.定义共同接口

    package com.mayikt.service;
    public interface OrderService {
    
        /**
         * 共同抽象的方法
         */
        void order();
    }
    

      

    2.定义被代理类实现共同的接口

    package com.mayikt.service.impl;
    
    import com.mayikt.service.OrderService;
    
    public class OrderServiceImpl implements OrderService {
        public void order() {
            System.out.println("执行订单业务逻辑代码");
        }
    }
    

      

    3.手写代理类OrderServiceProxy

    package com.mayikt.service.proxy;
    
    import com.mayikt.service.OrderService;
    import com.mayikt.service.impl.OrderServiceImpl;
    public class OrderServiceProxy implements OrderService {
        /**
         * 被代理对象
         */
        private OrderService orderService;
    
        public OrderServiceProxy(OrderService orderService) {
           this.orderService = orderService;
        }
        public void order() {
            System.out.println(">>>打印订单日志开始");
            orderService.order();
            System.out.println(">>>打印订单日志结束");
        }
    
    
    }
    

      

    4.测试

    package com.mayikt.service;
    
    import com.mayikt.service.cglib.proxy.CglibMethodInterceptor;
    import com.mayikt.service.impl.OrderServiceImpl;
    import com.mayikt.service.jdk.proxy.JdkInvocationHandler;
    import com.mayikt.service.proxy.OrderServiceProxy;
    import net.sf.cglib.core.DebuggingClassWriter;
    import net.sf.cglib.proxy.Enhancer;
    
    public class Client {
        public static void main(String[] args) {
           OrderService orderService = new OrderServiceProxy(new OrderServiceImpl());
           orderService.order();
        }
    }
    

      

    通过继承的方式实现静态代理

    1.定义共同接口

    package com.mayikt.service;
    public interface OrderService {
    
        /**
         * 共同抽象的方法
         */
        void order();
    }
    

      

    2.定义被代理类

    package com.mayikt.service.impl;
    
    import com.mayikt.service.OrderService;
    
    public class OrderServiceImpl implements  OrderService{
        public void order() {
            System.out.println("执行订单业务逻辑代码");
        }
    }
    

      

    3.手写代理类

    package com.mayikt.service.proxy;
    
    import com.mayikt.service.OrderService;
    import com.mayikt.service.impl.OrderServiceImpl;
    
    
    public class OrderServiceProxy extends OrderServiceImpl {
    
        public void order() {
            System.out.println(">>>打印订单日志开始");
            super.order();// 执行父类的order 方法OrderServiceImpl
            System.out.println(">>>打印订单日志结束");
        }
    
    }
    

      

    4、测试

    package com.mayikt.service;
    
    import com.mayikt.service.cglib.proxy.CglibMethodInterceptor;
    import com.mayikt.service.impl.OrderServiceImpl;
    import com.mayikt.service.jdk.proxy.JdkInvocationHandler;
    import com.mayikt.service.proxy.OrderServiceProxy;
    import net.sf.cglib.core.DebuggingClassWriter;
    import net.sf.cglib.proxy.Enhancer;
    
    
    public class Client  {
        public static void main(String[] args) {
            OrderService orderService = new OrderServiceProxy();
            orderService.order();
        }
    }
    

      

    动态代理

    1.动态代理:不需要关心代理类, jvm运行的时候自动创建代理类,不需要手动创建。
    2.动态代理实现方式有哪些?
    jdk动态代理和cglib原理
    3.jdk动态代理:jdk动态生成的代理类都是实现接口形式,所以被代理类必须实现接口(通过反射的方式实现)
    cglib代理:通过asm字节码技术实现动态生成代理类,运行时动态的生成一个被代理类的子类
    4.jdK动态代理要求被代理的类必须实现接口,当需要被代理的类没有实现接口时cglib代理是一个很好的选择
    5.spring默认会使用JDK的动态代理,但是如果目标对象没有实现接口,则默认会采用CGLIB代理;

    jdk实现动态代理

    1.定义共同接口

    package com.mayikt.service;
    public interface OrderService {
    
        /**
         * 共同抽象的方法
         */
        void order();
    }
    

      

    2.定义被代理类实现共同的接口

    package com.mayikt.service.impl;
    
    import com.mayikt.service.OrderService;
    
    public class OrderServiceImpl implements OrderService {
        public void order() {
            System.out.println("执行订单业务逻辑代码");
        }
    }
    

      

    3.创建生成动态代理类的类:JdkInvocationHandler

    package com.mayikt.service.jdk.proxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class JdkInvocationHandler implements InvocationHandler {
        /**
         * 被代理类对象 目标代理对象
         */
        private Object target;
    
        public JdkInvocationHandler(Object target) {
            this.target = target;
        }
    
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            //执行方法前打印日志
            System.out.println(">>>jdk打印订单日志开始:proxy:"+proxy.getClass().toString());
            Object reuslt = method.invoke(target, args);// java的反射机制执行方法 执行目标对象的方法
            //执行方法后打印日志
            System.out.println(">>>jdk打印订单日志结束");
            return reuslt;
        }
    
        /**
         * 使用jdk动态代理创建代理类
         *
         * @param <T>
         * @return
         */
        public <T> T getProxy() {
            return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
        }
    }
    

      

    4.测试

    package com.mayikt.service;
    
    import com.mayikt.service.cglib.proxy.CglibMethodInterceptor;
    import com.mayikt.service.impl.OrderServiceImpl;
    import com.mayikt.service.jdk.proxy.JdkInvocationHandler;
    import com.mayikt.service.proxy.OrderServiceProxy;
    import net.sf.cglib.core.DebuggingClassWriter;
    import net.sf.cglib.proxy.Enhancer;
    
    public class Client  {
        public static void main(String[] args) {
            // 1.使用jdk动态代理
            System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");//可以动态生成.class文件
            OrderService proxy = new JdkInvocationHandler(new OrderServiceImpl()).getProxy();
            proxy.order();
    
        }
    }
    

      

    使用cglib实现动态代理

     <dependency>
                <groupId>cglib</groupId>
                <artifactId>cglib</artifactId>
                <version>3.2.12</version>
         </dependency>
    

      

    2.定义被代理类

    package com.mayikt.service.impl;
    
    import com.mayikt.service.OrderService;
    
    public class OrderServiceImpl {
        public void order() {
            System.out.println("执行订单业务逻辑代码");
        }
    }
    

      

    3.创建生成动态代理类的类:CglibMethodInterceptor

    package com.mayikt.service.cglib.proxy;
    
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.Method;
    
    public class CglibMethodInterceptor implements MethodInterceptor {
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            System.out.println(">>>>cglib日志收集开始....");
            Object reuslt = proxy.invokeSuper(obj, args);
            System.out.println(">>>>cglib日志收集结束....");
            return reuslt;
        }
    }
    

      

    4.测试

    package com.mayikt.service;
    
    import com.mayikt.service.cglib.proxy.CglibMethodInterceptor;
    import com.mayikt.service.impl.OrderServiceImpl;
    import com.mayikt.service.jdk.proxy.JdkInvocationHandler;
    import com.mayikt.service.proxy.OrderServiceProxy;
    import net.sf.cglib.core.DebuggingClassWriter;
    import net.sf.cglib.proxy.Enhancer;
    
    public class Client  {
        public static void main(String[] args) {
            // 使用cglib动态代理
            System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\code");//可以动态生成class文件
            CglibMethodInterceptor cglibMethodInterceptor = new CglibMethodInterceptor();
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(OrderServiceImpl.class);
            enhancer.setCallback(cglibMethodInterceptor);
            OrderServiceImpl orderServiceImpl = (OrderServiceImpl) enhancer.create();
            orderServiceImpl.order();
    
        }
    }
    

      

    总结:看完有什么不懂的话欢迎在下方留言评论,记得点个赞哦!



  • 相关阅读:
    基于python创建一个简单的HTTP-WEB服务器
    基于python自动化测试平台与虚拟化技术结合的思考
    Net分布式系统之六:微服务之API网关
    Net分布式系统之五:C#使用Redis集群缓存
    Net分布式系统之二:CentOS系统搭建Nginx负载均衡
    Net分布式系统之一:系统整体框架介绍
    .Net微服务架构之运行日志分析系统
    Net分布式系统之七:日志采集系统(1)
    程序员如何选择未来的职业路线
    NET技术公众号已上线
  • 原文地址:https://www.cnblogs.com/lwh1019/p/12878355.html
Copyright © 2011-2022 走看看