【SSM框架解析】——前篇:详解动态代理【案例驱动】(案例源码自取)

发布时间:2025-05-02 13:05

2022-10-08 186 发布于辽宁

版权

举报

版权声明:

本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《 阿里云开发者社区用户服务协议》和 《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写 侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

✨前言

今天开始要学习SSM框架了,新的开始我决定用博客来记录自己的学习过程,和CSDN上的大佬们一同进步。

本学习是跟着B站动力节点学习,链接附上

在学习SSM框架之前,首先要先了解代理、静态代理、动态代理,那么这篇文章就先来详解动态代理

文章目录

✨前言一、代理模式二、代理模式的作用三、代理模式的分类四、什么是静态代理五、静态代理实现六、面向接口编程(重要)七、动态代理八、JDK动态代理要求(严格执行)九、JDK动态代理用到的类和接口**1)Proxy类****2)Method类**** 3)InvocationHandler接口 **十、CGLib动态代理✨总结

一、代理模式

客户端无法访问目标对象,通过代理对象进行访问,而且增强式访问。

优点:适合进行业务的扩展

举个例子:假如你是学校负责人,现在要举行一个明星演唱会,你需要请明星来学校进行演唱。但是你能直接练习到明星本人吗?不能,只能通过明星经纪人来联系。

那么这里的明星就是目标对象,经纪人就是代理对象。

再想一下,明星那么大的腕,肯定只进行唱歌,即进行主要业务,那么商量时间,地点,费用等等杂事,即业务的扩展

下图以刘德华举例:

二、代理模式的作用

1)控制目标对象的访问:对于目标对象不是想访问就能访问的,只能通过代理才能进行访问,这样一来目标对象只需要专注主要业务的实现,而不用关心其他事情。

2)增强功能:代理通过自身调创建目标对象,调用目标对象的主业务方法进行实现主业务,那么在调用的前后都可以增加自己的功能,即增强了功能

三、代理模式的分类

1)静态代理

2)动态代理,又为JDK动态代理,CGLib动态代理(子类代理)

四、什么是静态代理

他是代理模式的一种。

它具备一下特点:

目标对象和代理对象实现同一个业务接口目标对象必须实现接口代理对象在程序运行前就已经存在能够灵活的进行目标对象的切换,却无法进行功能的灵活处理(使用动态代理处理此问题)

五、静态代理实现

案例分析:

业务功能:请明星进行节目表演.

明星刘德华:目标对象(无法直接访问)

刘德华助理:代理对象(我们可以访问,他还可以跟明星对接)

我们 :客户端对象

代码实现 业务接口Service public interface Service { //规定的唱歌的业务功能 void sing(); } 目标对象: /** * 目标对象:刘德华,实现业务接口中的功能,进行唱歌表演 */ public class SuperStarLiu implements Service { @Override public void sing() { System.out.println("我是刘德华,我正在表演唱歌............"); } } 代理对象: public class Agent implements Service { //类中的成员变量设计为接口 public Service target; //目标对象 //传入目标对象,方法的参数设计为接口 public Agent(Service target){ this.target = target; } @Override public void sing() { System.out.println("预订时间.........."); System.out.println("预订场地.........."); //切记切记:业务功能必须由目标对象亲自实现 // SuperStarLiu liu = new SuperStarLiu(); // liu.sing(); // // SuperStarZhou zhou = new SuperStarZhou(); // zhou.sing(); //面向接口编程:调用时,接口指向实现类 target.sing(); System.out.println("结算费用.........."); } } 客户端对象 @Test public void testAgent(){ //测试功能 // SuperStarLiu liu = new SuperStarLiu(); // liu.sing(); // Agent agent = new Agent(); // agent.sing(); //有接口和实现类,必须使用接口指向实现类(规范) Service agent = new Agent(); agent.sing(); }

六、面向接口编程(重要)

类中的成员变量设计为接口

//类中的成员变量设计为接口 public Service target; //目标对象方法的形参设计为接口

//传入目标对象,方法的参数设计为接口 public Agent(Service target){ this.target = target; } 方法的返回值设计为接口
本例子暂时还未涉及,后面文章将涉及到。调用时接口指向实现类

//有接口和实现类,必须使用接口指向实现类(规范) Service agent = new Agent();

七、动态代理

可以看出,静态代理有个问题,如果我们需要扩展主要功能,即添加Service接口中的业务,那么我们同时需要在目标对象和代理对象的类中实现该方法。

例子,如果我们想看刘德华跳舞,(他也带愿意,假设愿意…),那么首先刘德华要愿意,实现跳舞,同时也要告诉经纪人刘德华可以跳舞才可以,这样一来我们就需要改动已经写好的源码,比较麻烦。这时动态代理就比较好的解决了这个问题。

代理对象在程序运行的过程中动态在内存构建.可以灵活的进行业务功能的切换.

八、JDK动态代理要求(严格执行)

目标对象必须实现业务接口JDK代理对象不需要实现业务接口JDK动态代理的对象在程序运行前不存在.在程序运行时动态的在内存中构建JDK动态代理灵活的进行业务功能的切换本类中的方法(非接口中的方法)不能被代理

九、JDK动态代理用到的类和接口

它是使用现在的工具类完成JDK动态实现.

1)Proxy类

它是java.lang.reflect.Proxy包下的类. 它有一个方法Proxy.newProxyInstance(…)专门用来生成动态代理对象.

public static Object newProxyInstance(ClassLoader loader, //类加载器 Class<?>[] interfaces,//目标对象实现的所有接口 InvocationHandler h //它就类似于Agent的功能,代理的功能和目标对象的业务功能调用在这 ) throws IllegalArgumentException {...}

2)Method类

反射用的类,用来进行目标对象的方法的反射调用.
method对象接住我们正在调用的方法sing(),show()

method==sing(),show() method.invoke();==>手工调用目标方法 sing(); show();

** 3)InvocationHandler接口 **

它是实现代理和业务功能的.我们在调用时使用匿名内部实现.

代码实现: public class ProxyFactory { //类中的成员变量设计为接口,目标对象 Service target; //传入目标对象 public ProxyFactory(Service target){ this.target = target; } //返回动态代理对象 public Object getAgent(){ return Proxy.newProxyInstance( //ClassLoader loader, 类加载器,完成目标对象的加载 target.getClass().getClassLoader(), //Class<?>[] interfaces,目标对象实现的所有接口 target.getClass().getInterfaces(), //InvocationHandler h,实现代理功能的接口 ,我们传入的是匿名内部实现 new InvocationHandler() { @Override public Object invoke( //创建代理对象 Object proxy, //method就是目标方法sing(),show() Method method, //目标方法的参数 Object[] args) throws Throwable { //代理功能 System.out.println("预订时间........"); //代理功能 System.out.println("预订场地........"); //主业务功能实现 //target.sing();还是写死了方法的调用, 不成 //sing(),show(),one() Object obj = method.invoke(target,args); //代理功能 System.out.println("结算费用........"); return obj; //切记:这个是目标方法的返回值 } } ); } }

十、CGLib动态代理

CGLib又称为子类.通过动态的在内存中构建子类对象,

重写父类的方法进行代理功能的增强.

如果目标对象没有实现接口,则只能通过CGLib子类代理来进行功能增强.

子类代理是对象字节码框架ASM来实现的.

注意:

被代理的类不能为final, 否则报错.

目标对象的方法如果为final/static, 那么就不会被拦截,即不会执行目标对象额外的业务方法。

public Object getProxyInstance(){ //1.使用工具类 Enhancer en=new Enhancer(); //2.设置父类 en.setSuperclass(target.getClass()); //3.设置回调函数 en.setCallback(this); //4.创建子类(代理)对象 return en.create(); ===>返回的是子类代理对象

✨总结

动态代理可以很方便的控制访问,功能增强,扩展功能,同时mybatis框架底层也是实现动态代理实现的,学习了动态代理可以更好的理解mybatis的底层实现原理。

下一篇文章将详解mybatis框架

本案例的源码将放在gitee上,点击进入。如果有帮助请点亮星星。

有收获的小伙伴三连一下吧,你们的喜欢是我更新的最大动力。

网址:【SSM框架解析】——前篇:详解动态代理【案例驱动】(案例源码自取) http://c.mxgxt.com/news/view/936339

相关内容

肯德基供应链管理案例详解.ppt
明星效应:明星带动品牌销售的案例解析
创业案例及分析(精选13篇)
体育赛事管理案例分析报告总结.docx
架构、框架、组件、插件浅谈理解
一年级数学《找规律》案例与评析(精选13篇)
明星代言营销案例分析.pptx
郑翔洲投资案例的模式分析
竞争品牌合作案例 品牌竞争者案例(15篇)
马航事件公关案例分析.doc

随便看看