当前位置: 首页 > 后端技术 > Java

面试官问你设计模式,你还在回答单例和工厂吗?了解代理模式

时间:2023-04-02 01:02:34 Java

面试官问你设计模式,你还在回答单例和工厂吗?了解代理模式,路过别错过。上一篇文章讲了反射。可以看我之前的文章或者微信搜索:木子的日夜编程。这篇文章准备写动态代理模式。1.原因先给大家一个理由,为什么要先学习动态代理呢,它是一种设计模式,如果能在工作中结合使用,代码绝对漂亮。面试官喜欢问的第二个面试问题包括设计模式。如果你掌握了这个设计模式,你下一份工作的薪水可能会高一点。第三,您可能已经看过很多源代码,包括但不限于Mybatis和Spring。他们的作者在写代码的时候充分利用了动态代理的思想。当你掌握了这门技术之后,你就能很好地理解那些框架。大佬们是怎么设计框架来提升自己能力的。2、搬家吧2.1先来说说代理。代理是代表另一个类提供功能的类。你可以理解为朋友圈的微商。厂家生产鞋子->微信从厂家批发鞋子,朋友圈卖->你买鞋子微信是代理商,代理商是鞋厂,你是用鞋厂生产的鞋的人,但是你需要处理微信。经常在网上看到UML图,下面画一张。2.2代理的优缺点优点:我的总结是扩展性高、智能化、职责明确缺点:成本增加(你买的鞋子可能会变贵,运输时间可能会变长)3、搬家前要安静。写一个静态代理的例子。packagetest;/***@author发现更多精彩可以关注公众号:木子的日夜编程*一个生活在互联网底层,做增删改查的码农,自命不凡的无知*@create2021-10-169:39**鞋厂规格*/publicinterfaceAShoeFactory{/****@paramname购鞋者姓名*@paramnum购鞋数量*/voidsellingShoes(Stringname,Integernum);}包测试;/***@author发现更多精彩可以关注公众号:木子的日夜编程*一个生活在互联网底层,做增删改查的码农,自命不凡的无知*@create2021-10-169:44**具体鞋厂:鸿星尔克*/publicclassErkeFactoryimplementsAShoeFactory{@OverridepublicvoidsellingShoes(Stringname,Integernum){System.out.println(name+"purchaseed"+num+"双鞋,放烟花庆祝!!);}}打包测试;/***@作者发现更多精彩关注公众号:木子的日夜编程*代理类:朋友圈XX*/publicclassProxyWechatMomentsimplementsAShoeFactory{publicProxyWechatMoments(){}publicProxyWechatMoments(ErkeFactoryerkeFactory){this.erkeFactory=erkeFactory;}ErkeFactoryerkeFactory;@OverridepublicvoidsellingShoes(Stringname,Integernum){erkeFactory.sellingShoes(name,数);}}测试:importtest.ErkeFactory;importtest.ProxyWechatMoments;/***@author发现更多精彩关注公众号:木子的日夜编程*/publicclassTest{publicstaticvoidmain(String[]args){//实际提供能力的类ErkeFactoryerkeFactory=newErkeFactory();//代理类ProxyWechatMomentsproxy=newProxyWechatMoments(erkeFactory);//冲动消费proxy.sellingShoes("最最最小的李子",10);}}测试输出结果:最多,最多,最小,李子买了10双鞋放烟花庆祝!!4.在motion中写一个静态代理,静态代理的实现比较简单缺点:扩展比较麻烦。如果我们在上面的例子中加入一个匹克鞋厂,我们需要修改代码。我们将在代理类中使用ifelse来区分购买哪个品牌的鞋子。4.1JDK打包测试;导入动态代理的java。lang.reflect.InvocationHandler;importjava.lang.reflect.Method;/***@author发现更多精彩关注公众号:木子日夜编程*动态代理类*/publicclassProxyDynamicHandlerimplementsInvocationHandler{privateAShoeFactoryshoeFactory;publicProxyDynamicHandler(){}publicProxyDynamicHandler(AShoeFactoryshoeFactory){this.shoeFactory=shoeFactory;}@OverridepublicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{//卖鞋前后做的是代理模式中经常用到的函数,使用System.out.println("The动态代理的好处,卖鞋前做点什么”);字符串名称=(String)args[0];//如果购买的人是怀念流年,我就不卖给他if("怀念流年".equals(name)){System.out.println("非卖品,谢谢!");}else{//这里用到了反射没有掌握的可以看我上一篇文章或者关注公众号:木子日夜编程的方法.invoke(shoeFactory,args);}System.out.println("动态代理的好处,卖鞋后做点什么");返回空值;}}importsun.applet.AppletClassLoader;importtest.AShoeFactory;importtest.ErkeFactory;importtest.ProxyDynamicHandler;importjava.lang.reflect.Proxy;/***@author发现更多精彩关注公众号:木子的一天和夜间编程*/publicclassTestDynamic{publicstaticvoidmain(String[]args){AShoeFactoryfactory=(AShoeFactory)Proxy.newProxyInstance(ErkeFactory.class.getClassLoader(),//类加载器ErkeFactory.class.getInterfaces(),//代理类的所有接口Jdk动态代理都是基于接口的//如果你学过Spring的动态代理,应该知道默认情况下,如果你的Service有接口,Spring会使用Jdk动态代理//如果你的Service如果没有接口,Spring将使用CGLIB//这个知识是我记忆中的,对不对?newProxyDynamicHandler(newErkeFactory()));factory.sellingShoes("正义的家伙",10);System.out.println("------------------华丽的分割线-----------------------");factory.sellingShoes("追忆流年",10);}}输出:动态代理的好处,在卖鞋之前做一些事情。仗义的帅哥买了10双鞋放烟花庆祝!!动态代理的好处,卖鞋后做点事----------------华丽的分界线-----------------------动态代理的好处,卖鞋前做点事,谢谢!动态代理的好处,卖鞋后做点什么4.2CGLIB动态代理CGLIB是一个非常强大的代码生成库,经常用在一些AOP框架中。CGLIB底层使用ASM来操作字节码。它用于字节码。老实说这不是很安全,但是用起来很爽。这是没有约束的最疯狂的技术。CGLIB实现动态代理的方式是认教父,利用字节码修改功能创建代理类(匹克鞋厂)的子类,在提供功能的时候使用代理类的功能,就像花钱找人一样父亲的一个原因注:这里的干爹是那种,70年代和80年代那种很纯洁的那种,两家人的关系很好,干爹不是现代意义上的。pom.xmlcglibcglib3.3.0包测试;/***@作者发现更多精彩关注公众号:木子的日夜编程*/publicclassPeakFactory{publicvoidsellingShoes(Stringname,Integernum){System.out.println(name+"买了"+num+"双Peak鞋子,放烟花庆祝!!!);}}CustomMethodHandler:packagetest;importnet.sf.cglib.proxy.MethodInterceptor;importnet.sf.cglib.proxy.MethodProxy;importjava.lang.reflect.Method;/***@作者发现更多精彩关注公众号:木子的日夜编程*/publicclassProxyDynamicByCglibimplementsMethodInterceptor{@OverridepublicObjectintercept(Objectobj,Methodmethod,Object[]args,MethodProxyproxy)throwsThrowable{//做卖鞋前后的事情是一个代理模式中经常用到的函数,作为增强和过滤使用System.out.println("动态代理的好处,卖鞋前先做点什么");字符串名称=(String)args[0];//如果买的人是回忆流年,那我就不卖给他if("Chasing追忆时光".equals(name)){System.out.println("非卖品,谢谢!");}else{System.out.println("查看代理对象的父类:"+obj.getClass().getSuperclass());//调用业务类(父类)方法proxy.invokeSuper(obj,args);}System.out.println("动态代理的好处,卖鞋后做点什么");//本次测试不需要returnreturnnull;}}测试:importnet.sf.cglib.proxy.Enhancer;importtest.*;/***@author发现更多精彩关注公众号:木子的日夜编程*/publicclassTestDynamicCGLIB{publicstaticvoidmain(String[]args){Enhancerenhancer=newEnhancer();//重点设置真正提供方法的类作为父类Cglib使用其自己的字节码修改函数生成一个该类的子类对象enhancer.setSuperclass(PeakFactory.class);enhancer.setCallback(newProxyDynamicByCglib());//自定义IntrceptorPeakFactoryfactory=(PeakFactory)enhancer.create();factory.sellingShoes("正义帅哥",10);System.out.println("--------------------华丽的分割线-------------------------");factory.sellingShoes("追忆流年",10);}}输出:动态代理的好处,卖鞋前做点事看看代理对象的父类是什么:classtest.PeakFactory正义帅哥买了10双Peak鞋子放烟花庆祝!!动态代理的好处,卖鞋后做点什么----------------华丽的分界线--------------------------动态代理的好处,卖鞋前先做一些事情,谢谢!动态代理的好处,卖鞋之后做一些事情,很多地方都会用到代理模式。根据我的经验,你可以通过简单的使用来了解架构中的代码流程。你不需要探索得太深。当然,不鼓励您探索。知识说有时间可以去探索,如果你没有时间,先学习如何使用它。本文由博客多发平台OpenWrite发布!