Spring--BeanFactory 我就是我 2022-11-10 05:33 132阅读 0赞 原文网址:[Spring--BeanFactory\_IT利刃出鞘的博客-CSDN博客][Spring--BeanFactory_IT_-CSDN] # 其他网址 # > [Spring--FactoryBean\_feiying0canglang的博客-CSDN博客][Spring--FactoryBean_feiying0canglang_-CSDN] > [Spring-BeanFactory解读\_小工匠-CSDN博客][Spring-BeanFactory_-CSDN] > [spring的BeanFactory和ApplicationContext\_程序员欣宸的博客-CSDN博客][spring_BeanFactory_ApplicationContext_-CSDN] > [Spring IOC原理总结 - 知乎][Spring IOC_ -] # 简介 # **BeanFactory 和 FactoryBean** > <table> > <tbody> > <tr> > <td style="width:69px;"> <p><strong><strong>项</strong></strong></p> </td> > <td style="width:227px;"> <p><strong><strong>BeanFactory</strong></strong></p> </td> > <td style="width:353px;"> <p><strong><strong>FactoryBean</strong></strong></p> </td> > </tr> > <tr> > <td style="width:69px;"> <p><strong><strong>工厂</strong></strong></p> </td> > <td style="width:227px;"> <p>负责生产和管理bean的一个通用工厂。</p> <p>基于工厂模式实现。</p> </td> > <td style="width:353px;"> <p>也是一个工厂,但只创建一种对象。</p> </td> > </tr> > <tr> > <td style="width:69px;"> <p><strong><strong>作用</strong></strong></p> </td> > <td style="width:227px;"> <p>实例化、定位、配置对象及建立其依赖。</p> <p>IOC容器的核心接口。</p> </td> > <td style="width:353px;"> <p>可以创建复杂的bean。</p> <p>是一个接口。</p> <p>Spring自身就提供了70多个FactoryBean的实现。它们隐藏了实例化一些复杂Bean的细节,给上层应用带来了便利。</p> </td> > </tr> > <tr> > <td style="width:69px;"> <p><strong><strong>实现</strong></strong></p> </td> > <td style="width:227px;"> <p>DefaultListableBeanFactory、ApplicationContext、XmlBeanFactory等。</p> <p>比如:XmlBeanFactory解析XML生成bean,处理对象间的依赖关系。</p> </td> > <td style="width:353px;"></td> > </tr> > </tbody> > </table> **类关系** > ![20210317212910621.png][] > > 在[Bean生命周期--Bean的创建过程\_feiying0canglang的博客-CSDN博客][Bean_--Bean_feiying0canglang_-CSDN]里可以发现,这几个BeanFactory比较重要:AbstractApplicationContext、DefaultListableBeanFactory、AbstractBeanFactory。那来看一下详细的类关系: > > ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZlaXlpbmcwY2FuZ2xhbmc_size_16_color_FFFFFF_t_70][] > > 放眼望去,一脸懵逼。那介绍下这些类的作用: > > 1. BeanDefinitionRegistry: Spring 配置文件中每一个节点元素在 Spring 容器里都通过一个 BeanDefinition 对象表示,它描述了 Bean 的配置信息。而 BeanDefinitionRegistry 接口提供了向容器手工注册 BeanDefinition 对象的方法。 > 2. BeanFactory 接口位于类结构树的顶端 ,它最主要的方法就是 getBean(String beanName),该方法从容器中返回特定名称的 Bean,BeanFactory 的功能通过其他的接口得到不断扩展: > 3. ListableBeanFactory:该接口定义了访问容器中 Bean 基本信息的若干方法,如查看Bean 的个数、获取某一类型 Bean 的配置名、查看容器中是否包括某一 Bean 等方法; > 4. HierarchicalBeanFactory:父子级联 IOC 容器的接口。 > > 1. 子容器可通过接口方法访问父容器; 通过 HierarchicalBeanFactory 接口, Spring 的 IoC 容器可以建立父子层级关联的容器体系,子容器可以访问父容器中的 Bean,但父容器不能访问子容器的 Bean。 > 2. Spring 使用父子容器实现了很多功能,比如在 Spring MVC 中,展现层 Bean 位于一个子容器中,而业务层和持久层的 Bean 位于父容器中。这样,展现层 Bean 就可引用业务层和持久层的 Bean,而业务层和持久层的 Bean 则看不到展现层的 Bean。 > 5. ConfigurableBeanFactory:是一个重要的接口,增强了 IoC 容器的可定制性,它定义了设置类装载器、属性编辑器、容器初始化后置处理器等方法; > 6. AutowireCapableBeanFactory:定义了将容器中的 Bean 按某种规则(如按名字匹配、按类型匹配等)进行自动装配的方法; > 7. SingletonBeanRegistry:定义了允许在运行期间向容器注册单例 Bean 的方法; > 8. DefaultSingletonBeanRegistry:有缓存单例对象和单例工厂的属性(map),缓存已经注册的单例的属性(set);有注册单例bean的方法 > > 1. 属性 > > 1. singletonObjects:这个map缓存了单例对象,bean的名字为key,bean对象为value > 2. singletonFactories:这个map缓存了单例工厂,bean的名字为key,工厂对象为value > 3. registeredSingletons:这个set缓存了已经注册的单例。 > 2. 方法 > > 1. registerSingleton(String beanName, Object singletonObject):会将单例对象放到singleFactories、registeredSingletons # ApplicationContext # **BeanFactory与ApplicationContext** > 见:[Spring进阶--ApplicationContext\_feiying0canglang的博客-CSDN博客][Spring_--ApplicationContext_feiying0canglang_-CSDN] **AbstractApplicationContext的委托逻辑** > AbstractApplicationContext部分源码 > > public Object getBean(String name) throws BeansException { > this.assertBeanFactoryActive(); > return this.getBeanFactory().getBean(name); > } > > public <T> T getBean(String name, Class<T> requiredType) throws BeansException { > this.assertBeanFactoryActive(); > return this.getBeanFactory().getBean(name, requiredType); > } > > public Object getBean(String name, Object... args) throws BeansException { > this.assertBeanFactoryActive(); > return this.getBeanFactory().getBean(name, args); > } > > public <T> T getBean(Class<T> requiredType) throws BeansException { > this.assertBeanFactoryActive(); > return this.getBeanFactory().getBean(requiredType); > } > > 可以看到,对BeanFactory的实现都是**委托**给了getBeanFactory这个方法返回的实例,接口是组合,实现也是组合,这种清晰的设计是学习典范。 > > getBeanFactory:它是AbstractApplicationContext自己定义的抽象方法,实现类为AbstractRefreshableApplicationContext.class, > > public final ConfigurableListableBeanFactory getBeanFactory() { > synchronized(this.beanFactoryMonitor) { > if (this.beanFactory == null) { > throw new IllegalStateException("BeanFactory not initialized or already closed - call 'refresh' before accessing beans via the ApplicationContext"); > } else { > return this.beanFactory; > } > } > } > > 实现很简单,它返回了它的成员:beanFactory。Spring容器初始化的时候调用refreshBeanFactory方法,该成员变量在refreshBeanFactory方法中实例化。所以容器初始化之后,AbstractApplicationContext就具备了bean管理配置的能力。 > 看了上述委托的方式,猜测ApplicationContext继承的Message接口也是这么操作的? > > 查看代码: > > public String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale) { > return this.getMessageSource().getMessage(code, args, defaultMessage, locale); > } > > public String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException { > return this.getMessageSource().getMessage(code, args, locale); > } > > public String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException { > return this.getMessageSource().getMessage(resolvable, locale); > } > > 如上所示,果然如此,Message相关的接口实现,都是getMessageSource()方法返回的实例在承担,getMessageSource()方法返回的是成员变量messageSource,该成员变量也是在Spring容器初始化的时候,调用initMessageSource方法生成的。 [Spring--BeanFactory_IT_-CSDN]: https://knife.blog.csdn.net/article/details/114884439 [Spring--FactoryBean_feiying0canglang_-CSDN]: https://blog.csdn.net/feiying0canglang/article/details/110549188 [Spring-BeanFactory_-CSDN]: https://blog.csdn.net/yangshangwei/article/details/74910935 [spring_BeanFactory_ApplicationContext_-CSDN]: https://blog.csdn.net/boling_cavalry/article/details/81603303 [Spring IOC_ -]: https://zhuanlan.zhihu.com/p/29344811 [20210317212910621.png]: /images/20221023/180a9a62069745e6b0ae68a8087bc7c7.png [Bean_--Bean_feiying0canglang_-CSDN]: https://blog.csdn.net/feiying0canglang/article/details/114555910 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZlaXlpbmcwY2FuZ2xhbmc_size_16_color_FFFFFF_t_70]: /images/20221023/8550be57aab346ea8fe8a2206c15e716.png [Spring_--ApplicationContext_feiying0canglang_-CSDN]: https://blog.csdn.net/feiying0canglang/article/details/109579302
还没有评论,来说两句吧...