IoC容器启动源码第1、2步分析-Bean是如何注册进IoC容器的?

我们接着Spring各模块说明和IoC容器启动源码简析继续分析,上一次,我们提到IoC容器的启动逻辑核心就在refresh方法中,今天深入分析,走到哪算哪:

@Override
public void refresh() throws BeansException, IllegalStateException {
    //上锁,保证只有一个线程进入
    synchronized (this.startupShutdownMonitor) {
        // 1. 准备要刷新的上下文
        prepareRefresh();

        // 2. 告诉子类去刷新内部的BeanFactory
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // 3. 准备当前上下文要用的BeanFactory
        prepareBeanFactory(beanFactory);

        try {
            // 4. 在子类中允许BeanFactory的Post-processing处理
            postProcessBeanFactory(beanFactory);

            // 5. 调用所有以Bean身份注册的BeanFactoryPostProcessor
            invokeBeanFactoryPostProcessors(beanFactory);

            // 6. 注册拦截Bean创建的processors
            registerBeanPostProcessors(beanFactory);

            // 7. 初始化上下文的消息来源
            initMessageSource();

            // 8. 初始化上下文的事件多播器
            initApplicationEventMulticaster();

            // 9. 在特定的容器子类中初始化特殊的Bean
            onRefresh();

            // 10. 检查并注册监听器Bean对象
            registerListeners();

            // 11. 实例化所有的(非懒加载)单例对象
            finishBeanFactoryInitialization(beanFactory);

            // 12. 最后一步:发布对应的事件
            finishRefresh();
        }
        //捕获 BeansException 异常
        catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                        "cancelling refresh attempt: " + ex);
            }

            // 销毁已创建的单例对象
            destroyBeans();

            // 重置“active”标识
            cancelRefresh(ex);

            // Propagate exception to caller.
            throw ex;
        }

        finally {
            // 重置内省缓存.
            resetCommonCaches();
        }
    }
}

那么我们今天就先来看第一步:

prepareRefresh

//准备要刷新的容器,设置它的启动时间和active标志。
protected void prepareRefresh() {
    // 设置启动时间戳
    this.startupDate = System.currentTimeMillis();
    //下面是两个标志位,类型均为AtomicBoolean
    this.closed.set(false);
    this.active.set(true);
    //日志相关
    if (logger.isDebugEnabled()) {
        if (logger.isTraceEnabled()) {
            logger.trace("Refreshing " + this);
        }
        else {
            logger.debug("Refreshing " + getDisplayName());
        }
    }

    // 为容器环境初始化一些属性源
    initPropertySources();

    // 验证一些属性,environment是AbstractApplicationContext中定义的一个ConfigurableEnvironment
    getEnvironment().validateRequiredProperties();

    // 加载刷新前的事件监听器
    if (this.earlyApplicationListeners == null) {
        this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
    }
    else {
        // 将本地的应用监听器设置为刷新前的状态
        this.applicationListeners.clear();
        this.applicationListeners.addAll(this.earlyApplicationListeners);
    }

    // 设置earlyApplicationEvents.
    this.earlyApplicationEvents = new LinkedHashSet<>();
}

可以看出,这一步中只是进行了一些属性设置,和事件机制的相关设置,事件机制我们暂且不关心,留到以后再谈。

接着第二步:

obtainFreshBeanFactory

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

我们在上一篇中已经看过了

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();
    return getBeanFactory();
}

refreshBeanFactory在AbstractRefreshableApplicationContext中的实现如下:

refreshBeanFactory

@Override
protected final void refreshBeanFactory() throws BeansException {
    //判断有没有beanFactory
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    //。。。
}

那么AbstractRefreshableApplicationContext初始化的时候倒底有没有beanFactory呢:

/** Bean factory for this context. */
@Nullable
private DefaultListableBeanFactory beanFactory;

并且通过之前ClassPathXmlApplicationContext构造方法的分析可知构造过程中也是没有初始化这个beanFactory的。

那么我们就继续看

@Override
protected final void refreshBeanFactory() throws BeansException {
    //。。。
    try {
        //创建beanFactory
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        beanFactory.setSerializationId(getId());
        customizeBeanFactory(beanFactory);
        loadBeanDefinitions(beanFactory);
        //设置beanFactory
        synchronized (this.beanFactoryMonitor) {
            this.beanFactory = beanFactory;
        }
    }
    catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

可以看到先通过createBeanFactory获取了一个DefaultListableBeanFactory对象:

createBeanFactory

protected DefaultListableBeanFactory createBeanFactory() {
    return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}

这里则是直接调用了DefaultListableBeanFactory的构造函数,并传入了一个BeanFactory,看名字大概知道是一个父级的BeanFactory。

public DefaultListableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
    super(parentBeanFactory);
}
public AbstractAutowireCapableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
    this();
    setParentBeanFactory(parentBeanFactory);
}
public AbstractAutowireCapableBeanFactory() {
    super();
    // 忽略自动注入(Autowiring)的接口
    ignoreDependencyInterface(BeanNameAware.class);
    ignoreDependencyInterface(BeanFactoryAware.class);
    ignoreDependencyInterface(BeanClassLoaderAware.class);
}
public AbstractBeanFactory() {
}

可见构建过程中也没做什么事。那就继续回到refreshBeanFactorysetSerializationId就不用看了,就是设置一下序列化Id,然后是customizeBeanFactory方法:

customizeBeanFactory

customize就是自定义,这里大概是做一些自定义配置的事情。

protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
    if (this.allowBeanDefinitionOverriding != null) {
        //允许BeanDefinition的重写
        beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
    }
    if (this.allowCircularReferences != null) {
        //允许循环引用
        beanFactory.setAllowCircularReferences(this.allowCircularReferences);
    }
}

loadBeanDefinitions

好的,那么继续来到loadBeanDefinitions,注意到这个方法有很多实现,例如分为注解的和XML的,可以猜测在这里读取元配置。

IoC容器启动源码第1、2步分析-Bean是如何注册进IoC容器的?

我们看其在AbstractXmlApplicationContext中的实现:

@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // 创建一个beanDefinitionReader,大概是用来读配置的。
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

    // 使用资源环境信息配置beanDefinitionReader
    beanDefinitionReader.setEnvironment(this.getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

    // 配置BeanDefinitionReader
    initBeanDefinitionReader(beanDefinitionReader);
    // 加载读取BeanDefinition
    loadBeanDefinitions(beanDefinitionReader);
}

我们看到,主要的逻辑还是在最后一行的loadBeanDefinitions中的,这是一个重载方法,并且可以猜想应该是解析XML文件并转换为BeanDefinition。

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
    Resource[] configResources = getConfigResources();
    //从资源中读取
    if (configResources != null) {
        reader.loadBeanDefinitions(configResources);
    }
    String[] configLocations = getConfigLocations();
    //从配置文件中读取
    if (configLocations != null) {
        reader.loadBeanDefinitions(configLocations);
    }
}

那我们肯定是继续看从配置文件中读取,感觉快要接近核心逻辑了:

@Override
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
    Assert.notNull(locations, "Location array must not be null");
    int count = 0;
    for (String location : locations) {
        count += loadBeanDefinitions(location);
    }
    return count;
}
@Override
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
    return loadBeanDefinitions(location, null);
}
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
    ResourceLoader resourceLoader = getResourceLoader();
    if (resourceLoader == null) {
        throw new BeanDefinitionStoreException(
                "Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
    }

    //使用 ResourcePatternResolver 读取
    if (resourceLoader instanceof ResourcePatternResolver) {
        // 可见,还是先将配置转成Resource,最终还是从resource加载BeanDefinition
        try {
            Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
            int count = loadBeanDefinitions(resources);
            if (actualResources != null) {
                Collections.addAll(actualResources, resources);
            }
            if (logger.isTraceEnabled()) {
                logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");
            }
            return count;
        }
        catch (IOException ex) {
            throw new BeanDefinitionStoreException(
                    "Could not resolve bean definition resource pattern [" + location + "]", ex);
        }
    }
    else {
        // Can only load single resources by absolute URL.
        Resource resource = resourceLoader.getResource(location);
        int count = loadBeanDefinitions(resource);
        if (actualResources != null) {
            actualResources.add(resource);
        }
        if (logger.isTraceEnabled()) {
            logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");
        }
        return count;
    }
}

那还是继续看从Resource中读取BeanDifinition:

XmlBeanDefinitionReader中的loadBeanDefinitions

@Override
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
    return loadBeanDefinitions(new EncodedResource(resource));
}
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
    Assert.notNull(encodedResource, "EncodedResource must not be null");
    if (logger.isTraceEnabled()) {
        logger.trace("Loading XML bean definitions from " + encodedResource);
    }

    Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
    if (currentResources == null) {
        currentResources = new HashSet<>(4);
        this.resourcesCurrentlyBeingLoaded.set(currentResources);
    }
    if (!currentResources.add(encodedResource)) {
        throw new BeanDefinitionStoreException(
                "Detected cyclic loading of " + encodedResource + " - check your import definitions!");
    }

    //开始读取
    try (InputStream inputStream = encodedResource.getResource().getInputStream()) {
        InputSource inputSource = new InputSource(inputStream);
        if (encodedResource.getEncoding() != null) {
            inputSource.setEncoding(encodedResource.getEncoding());
        }
        //读取的核心方法
        return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
    }
    catch (IOException ex) {
        throw new BeanDefinitionStoreException(
                "IOException parsing XML document from " + encodedResource.getResource(), ex);
    }
    finally {
        currentResources.remove(encodedResource);
        if (currentResources.isEmpty()) {
            this.resourcesCurrentlyBeingLoaded.remove();
        }
    }
}

又要跟进doLoadBeanDefinitions

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
        throws BeanDefinitionStoreException {

    try {
        // Document是用来解析XML文件的类
        Document doc = doLoadDocument(inputSource, resource);
        // 注册并获取BeanDefinition的数量
        int count = registerBeanDefinitions(doc, resource);
        if (logger.isDebugEnabled()) {
            logger.debug("Loaded " + count + " bean definitions from " + resource);
        }
        return count;
    }
    //catch...
}

这里提到一个registerBeanDefinitions,很有可能就是要把Bean注册进IoC容器了:

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
    BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
    // 获取操作之前BeanDefinition的数量
    int countBefore = getRegistry().getBeanDefinitionCount();
    // 从Resource注册BeanDefinition
    documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
    return getRegistry().getBeanDefinitionCount() - countBefore;
}

注意这里有一个getRegistry,很有可能就是用于注册BeanDefinition的类对象!
那么继续查看registerBeanDefinitions的源码:

public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
    this.readerContext = readerContext;
    doRegisterBeanDefinitions(doc.getDocumentElement());
}
//进行转换,将XML文件内容转换为BeanDefinition
protected void doRegisterBeanDefinitions(Element root) {
    BeanDefinitionParserDelegate parent = this.delegate;
    this.delegate = createDelegate(getReaderContext(), root, parent);

    //XML profile相关
    if (this.delegate.isDefaultNamespace(root)) {
        String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
        if (StringUtils.hasText(profileSpec)) {
            String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
                    profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
            // We cannot use Profiles.of(...) since profile expressions are not supported
            // in XML config. See SPR-12458 for details.
            if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
                            "] not matching: " + getReaderContext().getResource());
                }
                return;
            }
        }
    }

    //处理XML之前的操作
    preProcessXml(root);
    //转换为BeanDefinition
    parseBeanDefinitions(root, this.delegate);
    //处理XML之后的操作
    postProcessXml(root);

    this.delegate = parent;
}

preProcessXmlpostProcessXml这里为空,可能是等待子类重写,直接查看parseBeanDefinitions的源码:

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
    if (delegate.isDefaultNamespace(root)) {
        NodeList nl = root.getChildNodes();
        for (int i = 0; i < nl.getLength(); i++) {
            Node node = nl.item(i);
            if (node instanceof Element) {
                Element ele = (Element) node;
                // xml节点是否在默认的命名空间
                if (delegate.isDefaultNamespace(ele)) {
                    //进行转换
                    parseDefaultElement(ele, delegate);
                }
                else {
                    delegate.parseCustomElement(ele);
                }
            }
        }
    }
    else {
        delegate.parseCustomElement(root);
    }
}

查看这些转换节点的方法:

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
    // 如果节点名为“import”
    if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
        importBeanDefinitionResource(ele);
    }
    // 如果节点名为“alias”
    else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
        processAliasRegistration(ele);
    }
    // 如果节点名为“bean”
    else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
        processBeanDefinition(ele, delegate);
    }
    // 如果节点名为“beans”
    else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
        // 递归查找
        doRegisterBeanDefinitions(ele);
    }
}

那我们肯定还是节约时间(还一个小时熄灯了),只看processBeanDefinition这个方法:

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
    //可见,先是将<bean>节点转换为了一个BeanDefinitionHolder实例对象,字面上的意思是“BeanDefinition的持有类”
    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    if (bdHolder != null) {
        //这里大概是添加一些属性
        bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
        try {
            // 通过BeanDefinitionHolder对象进行注册!
            BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
        }
        catch (BeanDefinitionStoreException ex) {
            getReaderContext().error("Failed to register bean definition with name '" +
                    bdHolder.getBeanName() + "'", ele, ex);
        }
        // 发送注册事件
        getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    }
}

深入parseBeanDefinitionElement方法可知是通过构建了一个AbstractBeanDefinition对象来创建BeanDefinition实例的。

查看BeanDefinitionHolder的定义:

public class BeanDefinitionHolder implements BeanMetadataElement {

    private final BeanDefinition beanDefinition;

    private final String beanName;

    @Nullable
    private final String[] aliases;
    //...
}

不出其然,果然持有一个BeanDefinition对象。而getReaderContext().getRegistry()则是通过XmlReaderContext获取了一个BeanDefinitionRegistry对象。

这个对象是干什么的呢?根据我们之前的猜测,可能是注册BeanDefinition的。

那继续查看BeanDefinitionReaderUtils.registerBeanDefinition这个方法:

public static void registerBeanDefinition(
        BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
        throws BeanDefinitionStoreException {

    // 获取bean的名称
    String beanName = definitionHolder.getBeanName();
    //注意这个方法!可以说是经历了九九八十一难终于来到了最底层的方法
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

    // 如果bean有别名,为别名也注册
    String[] aliases = definitionHolder.getAliases();
    if (aliases != null) {
        for (String alias : aliases) {
            registry.registerAlias(beanName, alias);
        }
    }
}

BeanDefinitionRegistry这个接口很有意思,通过查看源码发现,DefaultListableBeanFactory实现了这个接口,是不是觉得DefaultListableBeanFactory这个名字很熟悉呢?在上一篇我们发现ApplicationContext会持有一个DefaultListableBeanFactory对象,那是不是意味着,它也承担着BeanDefinitionRegistry的功能呢?

DefaultListableBeanFactory的继承关系

查看DefaultListableBeanFactoryregisterBeanDefinition源码(貌似遇到大boss了,连代码都变长了呢):

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
        throws BeanDefinitionStoreException {

    // 一系列的验证操作
    Assert.hasText(beanName, "Bean name must not be empty");
    Assert.notNull(beanDefinition, "BeanDefinition must not be null");

    if (beanDefinition instanceof AbstractBeanDefinition) {
        try {
            ((AbstractBeanDefinition) beanDefinition).validate();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                    "Validation of bean definition failed", ex);
        }
    }

    // 通过beanName从beanDefinitionMap获取一个原有的BeanDefinition
    BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
    //如果原有对应的BeanDefinition
    if (existingDefinition != null) {
        //是否允许覆盖
        if (!isAllowBeanDefinitionOverriding()) {
            throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
        }
        // 比较新旧两者的角色关系?
        else if (existingDefinition.getRole() < beanDefinition.getRole()) {
            // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
            if (logger.isInfoEnabled()) {
                logger.info("Overriding user-defined bean definition for bean '" + beanName +
                        "' with a framework-generated bean definition: replacing [" +
                        existingDefinition + "] with [" + beanDefinition + "]");
            }
        }
        //后面的都出错,不允许覆盖
        else if (!beanDefinition.equals(existingDefinition)) {
            if (logger.isDebugEnabled()) {
                logger.debug("Overriding bean definition for bean '" + beanName +
                        "' with a different definition: replacing [" + existingDefinition +
                        "] with [" + beanDefinition + "]");
            }
        }
        else {
            if (logger.isTraceEnabled()) {
                logger.trace("Overriding bean definition for bean '" + beanName +
                        "' with an equivalent definition: replacing [" + existingDefinition +
                        "] with [" + beanDefinition + "]");
            }
        }
        // 放入beanDefinitionMap
        this.beanDefinitionMap.put(beanName, beanDefinition);
    }
    else {
        //Bean的创建是否开始
        if (hasBeanCreationStarted()) {
            // 不能修改启动中容器中的元素
            synchronized (this.beanDefinitionMap) {
                // 放入beanDefinitionMap
                this.beanDefinitionMap.put(beanName, beanDefinition);
                // 更新 beanDefinitionNames
                List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
                updatedDefinitions.addAll(this.beanDefinitionNames);
                updatedDefinitions.add(beanName);
                this.beanDefinitionNames = updatedDefinitions;
                // 移除手动注册的单例对象名
                removeManualSingletonName(beanName);
            }
        }
        else {
            // 不在启动中
            this.beanDefinitionMap.put(beanName, beanDefinition);
            this.beanDefinitionNames.add(beanName);
            // 移除手动注册的单例对象名
            removeManualSingletonName(beanName);
        }
        this.frozenBeanDefinitionNames = null;
    }

    // 大概起的是一个刷新的作用
    if (existingDefinition != null || containsSingleton(beanName)) {
        resetBeanDefinition(beanName);
    }
}

看完这段代码后,似乎已经可以看出一些东西了:

  • beanDefinitionMap应该是Map吧(可能是一个HashMap),存储着beanName->BeanDefinition的键值对?
  • 在Bean的注册中,最关键的两个类就是BeanDefinitionRegistryBeanDefinition

下面就让我们来验证一下:

DefaultListableBeanFactory

DefaultListableBeanFactory中的属性:

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
        implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {

    //。。。

    // 序列化id->DefaultListableBeanFactory引用的Map
    private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories = new ConcurrentHashMap<>(8);

    // 序列化id
    @Nullable
    private String serializationId;

    //使用允许BeanDefinition的覆盖
    private boolean allowBeanDefinitionOverriding = true;

    //是否允许(饿汉式?)的类加载
    private boolean allowEagerClassLoading = true;

    // 依赖的排序器
    @Nullable
    private Comparator<Object> dependencyComparator;

    //AutowireCandidateResolver
    private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();

    // 依赖类型->对应的注入值的map
    private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);

    // beanName->BeanDefinition的map,核心容器!
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

    // 依赖类型->beanName的map
    private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);

    // 依赖类型->单例bean名称的map
    private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);

    // 按注册顺序排序的bean名称list
    private volatile List<String> beanDefinitionNames = new ArrayList<>(256);

    // 按注册顺序排序的手动注册的单例bean名称
    private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);

    //缓存BeanDefinition的name,防止配置文件冻结
    @Nullable
    private volatile String[] frozenBeanDefinitionNames;

    //是否允许配置文件的缓存
    private volatile boolean configurationFrozen = false;

    //...
}

可见,里面确实有一个ConcurrentHashMap<String, BeanDefinition>类型的beanDefinitionMap,并且初始容量为256。目前暂不知道实例化后的单例对象放在了哪里。

BeanDefinition

而BeanDefinition的属性有(BeanDefinition是一个接口,基本上定义了这些属性的getter/setter方法,这里查看的是AbstractBeanDefinition的源码):

public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
        implements BeanDefinition, Cloneable {

    public static final String SCOPE_DEFAULT = "";

    public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;

    public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;

    public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;

    public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;

    public static final int DEPENDENCY_CHECK_NONE = 0;

    public static final int DEPENDENCY_CHECK_OBJECTS = 1;

    public static final int DEPENDENCY_CHECK_SIMPLE = 2;

    public static final int DEPENDENCY_CHECK_ALL = 3;


    public static final String INFER_METHOD = "(inferred)";


    @Nullable
    private volatile Object beanClass;

    @Nullable
    private String scope = SCOPE_DEFAULT;

    private boolean abstractFlag = false;

    @Nullable
    private Boolean lazyInit;

    private int autowireMode = AUTOWIRE_NO;

    private int dependencyCheck = DEPENDENCY_CHECK_NONE;

    @Nullable
    private String[] dependsOn;

    private boolean autowireCandidate = true;

    private boolean primary = false;

    private final Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap<>();

    @Nullable
    private Supplier<?> instanceSupplier;

    private boolean nonPublicAccessAllowed = true;

    private boolean lenientConstructorResolution = true;

    @Nullable
    private String factoryBeanName;

    @Nullable
    private String factoryMethodName;

    @Nullable
    private ConstructorArgumentValues constructorArgumentValues;

    @Nullable
    private MutablePropertyValues propertyValues;

    private MethodOverrides methodOverrides = new MethodOverrides();

    @Nullable
    private String initMethodName;

    @Nullable
    private String destroyMethodName;

    private boolean enforceInitMethod = true;

    private boolean enforceDestroyMethod = true;

    private boolean synthetic = false;

    private int role = BeanDefinition.ROLE_APPLICATION;

    @Nullable
    private String description;

    @Nullable
    private Resource resource;
    //...
}

可见基本上都是在XML中配置的Bean信息。

走完我们上述这些流程后,已经向ApplicationContext中的ConfigurableListableBeanFactory注册进了Bean,基本可以断定ApplicationContext实现BeanFactory的功能就是通过了组合的方式,毕竟BeanDefinition注册都是在内部的ConfigurableListableBeanFactory中。

好了,快熄灯了,refresh后面的步骤留到以后再继续吧。

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/ioc%e5%ae%b9%e5%99%a8%e5%90%af%e5%8a%a8%e6%ba%90%e7%a0%81%e7%ac%ac1%e3%80%812%e6%ad%a5%e5%88%86%e6%9e%90-bean%e6%98%af%e5%a6%82%e4%bd%95%e6%b3%a8%e5%86%8c%e8%bf%9bioc%e5%ae%b9%e5%99%a8%e7%9a%84/

(0)
彭晨涛彭晨涛管理者
上一篇 2020年5月14日
下一篇 2020年5月15日

相关推荐

发表回复

登录后才能评论