全国免费咨询:

13245491521

VR图标白色 VR图标黑色
X

中高端软件定制开发服务商

与我们取得联系

13245491521     13245491521

2024-05-25_详解Spring中IOC容器的顶层接口

您的位置:首页 >> 新闻 >> 行业资讯

详解Spring中IOC容器的顶层接口 点击关注公众号,“技术干货”及时达! ?思考,输出,沉淀。用通俗的语言陈述技术,让自己和他人都有所收获。 作者:毅航?? ?「IOC(Inverse of Control,控制反转)可以说是Spring中的核心设计理念之一,其出现的目的在于降低组件之间的耦合度,从而提高代码的可维护性和可测试性。」 而IOC容器作为Spring框架的核心组件之一,其负责管理应用程序中bean的对象生命周期和依赖关系。为此Spring内部提供复杂的容器架构来完成这一功能,这也就导致了Spring中容器有下图所示的错综复杂的体系结构。 ?注:本篇重点对Spring容器中的顶层接口:HierarchicalBeanFactory、ListableBeanFactory、AutowireCapableBeanFactory进行分析介绍。 ?面对如此复杂的结构初学者可能会感到茫然无措。如果你也有相同的疑惑,不妨跟着笔者的思路来重新梳理Spring中IOC容器间关系,理清Spring中的容器体系,体会Spring中IOC的设计精髓。 (注:不了解IOC相关知识的读者可参考笔者之前文章:深入探究控制反转(IOC)与依赖注入(DI)间的关系)(https://juejin.cn/post/7355740605274177547) 进行了解 ) 万物之始——BeanFactory结合一开始的UML类图不难看出,在Spring中所有的容器都会扩展于BeanFactory这个顶层接口。依据设计模式的中的单一职责原则来看:「一个类或模块应该有且仅有一个引起它变化的原因」。 换句话说,一个类或模块应该只负责一种类型的任务或功能。「这也就意味着一个类或模块应该专注于完成特定的功能,而不应该承担过多的责任。」 因此BeanFactory作为IOC容器的顶层接口,其所负责实现的功能应该是最简单。明确了这点后,我们来看BeanFactory的相关源码也就会变的豁然开朗。 publicinterfaceBeanFactory{ /** *获取bean信息 **/ ObjectgetBean(Stringname)throwsBeansException; //...省略getBean各类重载方法 /** *检测bean是否存在于容器 **/ booleancontainsBean(Stringname); /** *判断bean的类型信息 **/ booleanisSingleton(Stringname)throwsNoSuchBeanDefinitionException; booleanisPrototype(Stringname)throwsNoSuchBeanDefinitionException; booleanisTypeMatch(Stringname,ResolvableTypetypeToMatch)throwsNoSuchBeanDefinitionException; booleanisTypeMatch(Stringname,ClasstypeToMatch)throwsNoSuchBeanDefinitionException; /** *获取bean的别名信息 **/ String[]getAliases(Stringname); } 不难发现,BeanFactory接口中定义的IOC容器的基本行为包括:Bean实例获取、判断Bean是否存在、Bean别名获取等行为。「总的来看,BeanFactory接口是Spring框架中IOC容器的核心接口之一,它负责管理和控制应用程序中的对象,从而定义了IOC和DI的核心功能。」 进一步,通过BeanFactory开发人员可以轻松地管理和维护应用程序中的各种组件,从而提高了代码的可维护性和可测试性。 枚举Bean实例——ListableBeanFactory在Spring中ListableBeanFactory 继承自 BeanFactory接口,因此其除了扩展了BeanFactory基本的功能外,其还提供了更强大的检索和操作Bean的功能。 换句话,ListableBeanFactory 提供了检索Bean对象更多方式,让我们在获取Bean时,不再拘泥于BeanFactroy中getBean(String name)通过beanName获取Bean实例的方式,「而是提供了按类型、名称模式、注解等条件批量检索 Bean的方式」。其内部相关源码如下: publicinterfaceListableBeanFactoryextendsBeanFactory{ //省略一些同名重载方法 /** *按类型获取Bean实例 ***/ String[]getBeanNamesForType(ResolvableTypetype); /** *获取所有Bean的名称 ***/ String[]getBeanDefinitionNames(); /** *按注解获取Bean实例 ***/ String[]getBeanNamesForAnnotation(Class?extendsAnnotationannotationType); 例如,如果想获取容器中所有类型为UserService类型的Bean的名称,代码可写成如下形式: //构建上下文环境 ApplicationContextcontext=newClassPathXmlApplicationContext("beans.xml"); //获取工厂 ListableBeanFactoryfactory=(ListableBeanFactory)context; //调用ListableBeanFactory中的getBeanNamesForType方法 String[]serviceBeanNames=factory.getBeanNamesForType(UserService.class); //循环打印 for(StringbeanName:allBeanNames){ System.out.println("Beanname:"+beanName); } 容器间的继承——HierarchicalBeanFactory在google翻译中Hierarchical一词被解释为:"分层的、等级的"的含义。而在Spring框架中,HierarchicalBeanFactory提供了一种维护Bean工厂间父子关系的机制。「即每个 HierarchicalBeanFactory 可以有一个父工厂,同时也可以作为其他工厂的父工厂」。其内部方法也比较简洁: publicinterfaceHierarchicalBeanFactoryextendsBeanFactory{ @Nullable BeanFactorygetParentBeanFactory(); booleancontainsLocalBean(Stringname); } 其中,getParentBeanFactory()的作用在于获取当前容器的父BeanFactory对象;而方法 containsLocalBean(String name) 则用于检查当前本地的容器中是否有指定名称的Bean ,而不会往上找父 BeanFactory。该方法要与我们熟知的getBean进行区分,对于getBean而言,其会首先从当前 BeanFactory 开始查找是否存在指定的 Bean ,如果当前找不到就依次向上找父 BeanFactory 直到找到为止返回,如果找不到则会抛出 NoSuchBeanDefinitionException的相关异常。 ?这里不妨思考一个问题:HierarchicalBeanFactory 可以使得容器间产生继承关系,假如现在有两个容器A和B,其中容器A为B的父容器,那么容器A和容器B中是否可以有重名的Bean实例呢?欢迎评论区留下你的想法~~~ ?总之,HierarchicalBeanFactory 提供了一种灵活的机制来管理 bean 工厂之间的父子关系,并允许在这种分层结构中共享配置、资源和bean定义。 自动装配的基石——AutowireCapableBeanFactory在Spring中,AutowireCapableBeanFactory 提供了 Bean实例自动装配(Autowiring)的核心功能。其允许对现有的Bean实例进行自动装配,注入其依赖。 此外,它还支持调用Bean的初始化和销毁方法,以及应用 BeanPostProcessor 进行自定义的前后处理。 publicinterfaceAutowireCapableBeanFactoryextendsBeanFactory{ //省略其他内部属性即重名重载方法 //对现有的 Bean 实例进行自动装配。 voidautowireBean(ObjectexistingBean) //创建一个新的 Bean 实例,并自动装配其依赖。 TTcreateBean(ClassbeanClass) //配置现有的 Bean 实例,包括自动装配和应用后置处理器。 ObjectconfigureBean(ObjectexistingBean,StringbeanName) //初始化现有的Bean实例,包括调用初始化方法和后置处理器 voidinitializeBean(ObjectexistingBean,StringbeanName) //销毁现有的 Bean 实例,包括调用销毁方法和后置处理器。 voiddestroyBean(ObjectexistingBean,StringbeanName) } 接下来,我们便通过一个例子来演示如何通过AutowireCapableBeanFactory来完成自动装配,开始之前我们先定义如下UserMapper、UserService两个类,其依赖关系如下所示: publicclassUserMapper{ publicvoiddoSomething(){ System.out.println("DoingsomethinginMyRepository"); } } publicclassUserService{ @Autowired privateUserMapperuserMapper; publicvoidperformAction(){ userMapper.doSomething(); } } (注:此时省略UserMapper、UserService的beans.xml的配置信息) //加载Spring配置文件ApplicationContextcontext=newClassPathXmlApplicationContext("beans.xml"); //获取AutowireCapableBeanFactory AutowireCapableBeanFactoryfactory=context.getAutowireCapableBeanFactory(); //对现有Bean实例进行自动装配 UserServiceuserService=newUserService(); factory.autowireBean(existingBean); 在上述代码中,通过 autowireBean 方法,UserService 实例的 userMapper 字段将会被自动注入一个 UserMapper 实例,从而可以正确调用 performAction 方法。 总的来看,AutowireCapableBeanFactory 提供了灵活的自动装配和Bean管理功能,使你可以在运行时动态地创建和配置 Bean实例,并自动注入它们的依赖。 总结本文从BeanFactory入手,详细的对Spring容器中的顶层接口:HierarchicalBeanFactory、ListableBeanFactory、AutowireCapableBeanFactory进行分析介绍。具体来看 「HierarchicalBeanFactory」:支持父子 Bean 工厂的层次结构,允许在父工厂中查找 Bean。「ListableBeanFactory」:提供批量检索和查询 Bean的功能,支持按类型和注解查找Bean。「AutowireCapableBeanFactory」:提供自动装配和Bean生命周期管理功能,支持动态创建和配置 Bean。点击关注公众号,“技术干货”及时达! 阅读原文

上一篇:2019-09-04_腾讯这支广告为了一块钱,真的走心了! 下一篇:2024-07-04_「转」【CTR媒介智讯月读广告】2024年1-5月广告市场花费同比上涨2.9%

TAG标签:

16
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设网站改版域名注册主机空间手机网站建设网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。
项目经理在线

相关阅读 更多>>

猜您喜欢更多>>

我们已经准备好了,你呢?
2022我们与您携手共赢,为您的企业营销保驾护航!

不达标就退款

高性价比建站

免费网站代备案

1对1原创设计服务

7×24小时售后支持

 

全国免费咨询:

13245491521

业务咨询:13245491521 / 13245491521

节假值班:13245491521()

联系地址:

Copyright © 2019-2025      ICP备案:沪ICP备19027192号-6 法律顾问:律师XXX支持

在线
客服

技术在线服务时间:9:00-20:00

在网站开发,您对接的直接是技术员,而非客服传话!

电话
咨询

13245491521
7*24小时客服热线

13245491521
项目经理手机

微信
咨询

加微信获取报价