前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring IOC容器分析(1) -- BeanFactory

Spring IOC容器分析(1) -- BeanFactory

作者头像
YGingko
发布2017-12-28 15:14:09
7830
发布2017-12-28 15:14:09
举报
文章被收录于专栏:海说

搭建好源码阅读环境后,就可以慢慢走进Spring殿堂了。IOC是Inversion of Control的缩写,控制反转的意思。很多人可能都知道IOC是spring的核心,将对象的创建初始化等权限交由容器控制,从而减少对象之间的依赖。甚至听说过BeanFactory,知道BeanFactory是实现IOC机制的核心,但是具体如何实现,却不是十分清楚。下面我们来一步一步深入理解BeanFactory。

引例

在spring工程应用中,一般用spring注解@Autowired来自动加载依赖对象,如下所示:

代码语言:javascript
复制
public class MerchantController {

    @Autowired
    private final MerchantService merchantService;
}

注解@Autowired使得对象加载很方便,使得对象依赖间管理很容易。但是依据守恒定律,对象的加载、创建、初始化等步骤是不会减少的,这里使用简单了,那必然在别的地方执行了对象的加载、创建、初始化的过程。实际上这个加载、创建、初始化的过程是在Spring源码BeanFactory中完成的。

BeanFactory

首先看下BeanFactory源码,BeanFactory是一个祖宗级接口,定义了Bean Factory的各种基本方法。spring中各种具体bean工厂均是对BeanFactory接口的实现,如DefaultListableBeanFactory,SimpleJndiBeanFactory,StaticListableBeanFactory等。

作为一个接口,BeanFactory定义的方法非常简单,而且都是一些常用的方法模板,如:getBean()containsBean()isSingleton()方法。BeanFactory接口如下:

代码语言:javascript
复制
package org.springframework.beans.factory;

import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;

public interface BeanFactory {

    String FACTORY_BEAN_PREFIX = "&";

    Object getBean(String name) throws BeansException;

    <T> T getBean(String name, Class<T> requiredType) throws BeansException;

    <T> T getBean(Class<T> requiredType) throws BeansException;

    Object getBean(String name, Object... args) throws BeansException;

    <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

    boolean containsBean(String name);

    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

    Class<?> getType(String name) throws NoSuchBeanDefinitionException;

    String[] getAliases(String name);
}

顾名思义,getBean()方法是用来获取Bean工厂中存储的对象实例,根据name即可获得对应的对象,也即是配置文件(暂认为xml)中定义的idcontainsBean是用于判断该Bean工厂中是否含有name所对应的对象。isSingleton是判断该name所对应的Bean是否是共享的单例,如果true的话,当调用getBean()方法时便会返回该Bean。

getBean()方法,应该能够猜测出:Bean工厂是先将name-bean作为一个键值对存储在一个容器中,当调用getBean()方法时,根据key值取出对应的bean值。实际上,spring中的确是这么做的。

根据UML类图关系,找到BeanFactory接口对应的默认实现类DefaultListableBeanFactory,如下图所示。

DefaultListableBeanFactoryUML类图关系
DefaultListableBeanFactoryUML类图关系

查看DefaultListableBeanFactory源码,发现:属性中beanDefinitionMap用于存储name-bean键值对,也即是存放Bean工厂实例化后的bean。截取部分源码如下:

代码语言:javascript
复制
package org.springframework.beans.factory.support;

@SuppressWarnings("serial")
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
        implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
    ............
    /** Map of bean definition objects, keyed by bean name */
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);
    ...........
}

从源码可以发现,存储键值对的容器是ConcurrentHashMap,它是一个基于HashMap的高并发容器,具有很好的线程安全性。其存储的不是String-Object键值对,而是String-BeanDefinition键值对,也就是说创建的bean对象不是以Object类型存储的,而是Bean Definition类型存储。为什么是这样的呢?请听下回分解

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-11-09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引例
  • BeanFactory
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档