当前位置: 首页> 健康> 知识 > Spring之代理模式和Spring-IOCDI

Spring之代理模式和Spring-IOCDI

时间:2025/7/11 23:11:55来源:https://blog.csdn.net/qq_70314704/article/details/140109053 浏览次数:0次

代理模式

《租房》

今天是7月1日,我毕业了。

于是我开始准备找工作,但是有一个好消息和坏消息。

好消息是:我找到了一份月薪20000的工作

坏消息是:这工作的地方也太特么远了吧!!!💢💢💢💢

于是我决定再公司附近租一个房子,可是问题是,我找不到房东啊?!!

突然看到电线杆上贴的小广告:“低价租房,接收短租,有意者请联系:173xxxxxxxxxx”,我毫不犹豫拨通了电话

。。。

半个小时后,中介来了,还带我参观了房子,签了合同

Yes!!我租到了!!

。。。过了一个月,我才发现,这特么是个黑中介😇😇😇

静态代理

租房接口Rent

public interface Rent {void rent();
}

房东类LandHolder😑

public class LandHolder implements Rent {@Overridepublic void rent() {System.out.println("房东:租房");}}

代理类Mediator🧐

这种代理方式被称为静态代理,因为这个代理只针对一个被代理的对象

比如这个Mediator只能代理LandHolder,因为他不是一个合规中介公司的中介,在合同里面还黑了我800块钱

public class Mediator implements Rent {private Rent rent;public void setRent(Rent rent) {this.rent = rent;}@Overridepublic void rent() {System.out.println("中介:看房");System.out.println("中介:签合同");rent.rent();}
}

我(大冤种🙃🙃)

public class Main {public static void main(String[] args) {LandHolder landHolder = new LandHolder();Mediator mediator = new Mediator();mediator.setRent(landHolder);mediator.rent();}
}//输出结果
//中介:看房
//中介:签合同
//房东:租房

动态代理:JDK的动态代理

三个月过去,我也从这家公司离职了,不过不是我自己辞职,是被辞退的🤐🤐🤐

理由是:我只会静态代理,不符合公司要求(此时我心里一万批🐴在奔腾)

。。。

于是,我去找了一家正规的中介公司(这家公司叫JDK,并且只支持接口代理的动态代理)

不得不说,中介公司就是强大,什么都能代理,租房、租车,甚至是过年租女朋友…

ok,话说回来,他是怎么实现的呢?

同样的

租房接口Rent

public interface Rent {void rent();
}

房东类LandHolder😑

public class LandHolder implements Rent {@Overridepublic void rent() {System.out.println("房东:租房");}}

JDK这家公司就强大在,他给我办理租房服务的时候,会每次都去找到房东对象landHolder ,然后为我去分配处理器invocationHandler ,每次在invocationHandler 中实现办理的逻辑(@Override部分),然后再去创建了proxy代理对象办理业务,真牛逼!!怪不得说什么都能代理呢

public static void JDKProxy(){LandHolder landHolder = new LandHolder();InvocationHandler invocationHandler = new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("中介:看房");System.out.println("中介:签合同");method.invoke(landHolder, args);return null;}};Class<?>[] interfaces = {Rent.class};Rent proxy = (Rent) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), interfaces, invocationHandler);proxy.rent();}
}

动态代理:CGLIB的动态代理

就当我办理好的时候,CGLIB这家代理公司也找上了我,说:JDK能动态代理,我也能动态代理,而且我还是基于类的代理…

我次奥,没听说过啊,于是我线下约了中介,他给我介绍说,我们的代码实现是这样的

房东类LandHolder😑

public class LandHolder implements Rent {@Overridepublic void rent() {System.out.println("房东:租房");}}

我:等等?

中介:怎么了?

我:我靠?!接口呢?

中介:我们是基于类的,不需要那套规则,你就放心好了

我:我看看怎么回事…

。。。。

我:所噶寺内~~,首先找到房东对象landHolder ,然后让landHolder 去造了个儿子模板enhancer ,然后在实现处理逻辑的处理器methodInterceptor ,并添加到enhancer ,再让enhancer.create()一个代理对象,最后代理对象帮我办理业务。

public static void CGLIBProxy(){LandHolder landHolder = new LandHolder();Enhancer enhancer = new Enhancer();enhancer.setSuperclass(LandHolder.class);MethodInterceptor methodInterceptor = new MethodInterceptor() {@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("中介:看房");System.out.println("中介:签合同");method.invoke(landHolder, objects);return null;}};enhancer.setCallback(methodInterceptor);Rent proxy = (Rent) enhancer.create();proxy.rent();}

不对,好像JDK和CGLIB的代理也能坑我钱!!!😣😣😣

总结

代理模式,就是在不改变原有代码的基础上,增强功能

简单来说就是,房子仍然是房东出租的,但是在出租前后代理对象能做一些操作,比如租房前带我看房、租房后给我钥匙之类的。。。

代理分为静态代理和动态代理

  • 静态代理

    • 缺点:每次需要代理时就需要创建一个代理对象,代码的重用性低,并且增加了开发成本

      就比如租房就要一个专门代理,租车也需要一个专门代理,老板没钱发工资啊

  • 动态代理

    • 优点:灵活性高,代码重用性提高

      每次的代理的前后逻辑都交给了处理器(invocationHandler /methodInterceptor )去实现,其他的部分都是重复部分,就交给JDK和CGLIB去封装了

Spring的IOC与DI

技术:xml文件 + 反射

IOC(inverse of control):控制反转

DI(dependicies injection):依赖注入

依赖注入有

  • 属性注入(使用set方法)

  • 构造注入(使用构造方法)

在以前的代码中,创建并使用对象是如下

User user= new User();
//构造方法、设置属性...
System.out.println("user = " + user);
//user = User(name=周珍珍, age=18, userInfo=UserInfo(address=成都理工大专, info=历史悠久的恐龙大专), hobbies=[唱歌, 跳舞], friend=[刘旭, 李淑文, 敖国珍], girlFriend=[刘旭], family={李俊瑶=19, 李虹霖=21}, properties={性格=温和, 身高=150})

但是,引入IOC的概念后,谁创建谁管理,所以就将对象的创建和管理的权力交给了Spring,这就是控制反转

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--    声明一个UserInfo对象--><bean class="cn.cnmd.spring.pojo.UserInfo" id="userInfo"><property name="address" value="成都理工大专"/><property name="info" value="历史悠久的恐龙大专"/></bean><!--    声明一个User对象--><bean class="cn.cnmd.spring.pojo.User" id="user"><!--        简单数据类型--><property name="name" value="周珍珍"/><property name="age" value="18"/><!--引用数据类型--><property name="userInfo" ref="userInfo"/><!--数组类型--><property name="hobbies"><array><value>唱歌</value><value>跳舞</value></array></property><!--集合类型--><property name="friend"><list><value>刘旭</value><value>李淑文</value><value>敖国珍</value></list></property><property name="girlFriend"><set><value>刘旭</value></set></property><property name="family"><map><entry key="李俊瑶" value="19"/><entry key="李虹霖" value="21"/></map></property><!--配置文件类型--><property name="properties"><props><prop key="性格">温和</prop><prop key="身高">150</prop></props></property></bean>
</beans>

通过applicationContext.xml配置文件的bean的声明,从而让创建对象和管理对象的步骤省略,只需要调用对象

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");User user = (User) applicationContext.getBean("user");
System.out.println("user = " + user);
//user = User(name=周珍珍, age=18, userInfo=UserInfo(address=成都理工大专, info=历史悠久的恐龙大专), hobbies=[唱歌, 跳舞], friend=[刘旭, 李淑文, 敖国珍], girlFriend=[刘旭], family={李俊瑶=19, 李虹霖=21}, properties={性格=温和, 身高=150})

是不是很方便呢?

关键字:Spring之代理模式和Spring-IOCDI

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: