Spring IoC源码分析

目录

介绍

BeanFactory

启动过程分析

创建Bean容器前的准备工作

创建Bean容器,加载并注册bean

准备Bean容器 prepareBeanFactory()

初始化所有的 singleton beans


介绍

首先来看一下最基本的启动 Spring 容器的例子:

ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");

上述代码是利用配置文件来启动一个 Spring容器的。大概意思也不难理解:就是在ClassPath 中寻找 xml配置文件,根据xml 配置文件内容来构建 ApplicationContext。(我们还可以使用AnnotationConfigApplicationContext 基于注解来使用)

ApplicationContext 继承结构图

1

IoC的核心:怎么通过配置文件来启动Spring的ApplicationContext的?

ApplicationContext 启动的过程中,会负责创建实例bean,往各个bean中注入依赖等。

 

BeanFactory

生产bean的工厂,它负责生产和管理各个bean实例。其实上面的ApplicationContext 就是一个BeanFactory。

BeanFactory 接口相关的主要继承结构:

2

  • ApplicationContext 继承了 ListableBeanFactory :通过这个接口,我们可以获取多个bean。看最顶层的BeanFactory源码可知 接口的方法都是获取单个 Bean
  •   HierarchicalBeanFactory,Hierarchical 单词本身已经能说明问题了,也就是说我们可以在应用中起多个 BeanFactory,然后可以将各个 BeanFactory 设置为父子关系。
  • AutowireCapableBeanFactory,自动装配 Bean。虽然ApplicationContext 并没有继承它,
    AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;

    但是在ApplicationContext 接口中有如上方法。

启动过程分析

 构造器

    ...
    public ClassPathXmlApplicationContext(
            String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
            throws BeansException {

        super(parent);

        //根据提供的路径,处理配置文件数组
        setConfigLocations(configLocations);
        if (refresh) {
            //核心方法
            refresh();
        }
    }
    ...

refresh()

ApplicationContext 建立起来以后,我们可以通过调用 refresh() 这个方法重建,refresh() 会将原来的 ApplicationContext 销毁,然后再重新执行一次初始化操作。

@Override
public void refresh() throws BeansException, IllegalStateException {
    //线程安全,避免当前refresh还没结束,又新来启动或销毁操作
    synchronized (this.startupShutdownMonitor) {
        // 准备工作,刷新前预处理
        prepareRefresh();

        // Tell the subclass to refresh the internal bean factory.
        //完成下面操作,配置文件会被解析成一个个 beanDefinition,注册到BeanFactory中
        //此时只是配置信息被提取出来,beanDefinition还未被初始化
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        //设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean
        prepareBeanFactory(beanFactory);

        try {

            //public interface BeanFactoryPostProcessor {
            //	void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
            //}
            //bean如果实现了BeanFactoryPoatProcessor 接口,那么在容器初始化以后,
            //Spring会负责调用里面的 postProcessBeanFactory()方法

            // Allows post-processing of the bean factory in context subclasses.
            //子类的扩展点,到这里,所有的bean 都被加载注册完了,但都还未被初始化
            postProcessBeanFactory(beanFactory);

            // Invoke factory processors registered as beans in the context.
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory);

            // Initialize message source for this context.
            //初始化当前 ApplicatonContext 的MessageSource
            initMessageSource();

            // Initialize event multicaster for this context.
            initApplicationEventMulticaster();

            // Initialize other special beans in specific context subclasses.
            onRefresh();

            // Check for listener beans and register them.
            registerListeners();

            // Instantiate all remaining (non-lazy-init) singletons.
            //重点
            //初始化所有的 singleton beans(lazy-init除外)
            finishBeanFactoryInitialization(beanFactory);

            // Last step: publish corresponding event.
            //最后,广播事件,初始化完成
            finishRefresh();
        }

        catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                        "cancelling refresh attempt: " + ex);
            }

            // Destroy already created singletons to avoid dangling resources.
            //销毁已经初始化的 singleton 的bean,避免有些beab一直占用资源 
            destroyBeans();

            // Reset 'active' flag.
            cancelRefresh(ex);

            // Propagate exception to caller.
            throw ex;
        }

        finally {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            resetCommonCaches();
        }
    }
}

创建Bean容器前的准备工作

protected void prepareRefresh() {
    // Switch to active.
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);

    if (logger.isDebugEnabled()) {
        if (logger.isTraceEnabled()) {
            logger.trace("Refreshing " + this);
        }
        else {
            logger.debug("Refreshing " + getDisplayName());
        }
    }

    // Initialize any placeholder property sources in the context environment.
    initPropertySources();

    // Validate that all properties marked as required are resolvable:
    // see ConfigurablePropertyResolver#setRequiredProperties
    //校验xml的配置文件
    getEnvironment().validateRequiredProperties();

    // Store pre-refresh ApplicationListeners...
    if (this.earlyApplicationListeners == null) {
        this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
    }
    else {
        // Reset local application listeners to pre-refresh state.
        this.applicationListeners.clear();
        this.applicationListeners.addAll(this.earlyApplicationListeners);
    }

    // Allow for the collection of early ApplicationEvents,
    // to be published once the multicaster is available...
    this.earlyApplicationEvents = new LinkedHashSet<>();
}

创建Bean容器,加载并注册bean

准备工作完成之后,执行下一个操作 obtainFreshBeanFactory() .

这个方法比较重要,这里将会初始化 BeanFactory、加载Bean、注册bean等,但此操作结束后,bean并没有完成初始化。

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {

    //关闭旧的 BeanFactory (如果有),创建新的 BeanFactory,加载 Bean 定义、注册 Bean 等等
    //如果之前有 BeanFactory 则关闭;没有,就会创建新的BeanFactory ,加载bean definition 注册bean等
    refreshBeanFactory();

    //返回刚创建的 BeanFactory
    return getBeanFactory();
}
@Override
protected final void refreshBeanFactory() throws BeansException {
    //如果当前 ApplicationContext 中已经加载过 BeanFactory 了,则销毁所有的 bean,并关闭BeanFactory
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    try {
        //初始化一个 DefaultListableBeanFactory
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        //用于 BeanFactory 的序列化
        beanFactory.setSerializationId(getId());
        //设置 BeanFactory 的两个配置属性:是否允许 Bean 覆盖、是否允许循环引用
        customizeBeanFactory(beanFactory);
        //加载BeanDefinition到 BeanFactory中
        loadBeanDefinitions(beanFactory);
        synchronized (this.beanFactoryMonitor) {
            this.beanFactory = beanFactory;
        }
    }
    catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

再回头看 ApplicationContext 的继承关系,ApplicationContext 继承自 BeanFactory,但是它不应该被理解为 BeanFactory 的实现类,而是说其内部持有一个实例化的 BeanFactory(DefaultListableBeanFactory)。以后所有的 BeanFactory 相关的操作其实是委托给这个实例来处理的。

上面 refreshBeanFactory() 方法中,实例化的是 DefaultListableBeanFactory,看上面的继承关系可知,ConfigurableListableBeanFactory 实现了BeabFactory 下面一层的所有的三个接口,而 ConfigurableListableBeanFactory 只有一个实现类 DefaultListableBeanFactory 。仔细看BeanFactory接口的继承关系,可知最底层的这个 DefaultListableBeanFactory 是最重要的 BeanFactory了。

这里,我们先了解一下 BeanDefinition。

这里的 BeabDefinition 就是我们所说的Spring 的Bean,我们自己定义的Bean 也会转换成 BeabDefinition 存在于Spring 的BeabFactory 中。

Bean在代码层面上可以理解为 BeanDefinition。BeanDefinition 中保存了我们的bean信息(bean指向哪个类,是否单例,是否懒加载等)

BeanDefinition 接口

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
    //可以看出,bean的作用域 默认只提供了 singleton 和 prototype 两种
    //其他的就是基于web引用中使用了
    String SCOPE_SINGLETON = "singleton";
    String SCOPE_PROTOTYPE = "prototype";
    int ROLE_APPLICATION = 0;
    int ROLE_SUPPORT = 1;
    int ROLE_INFRASTRUCTURE = 2;

    //bean继承
    //继承父bean的配置信息
    void setParentName(@Nullable String var1);

    //获得父bean
    @Nullable
    String getParentName();

    //设置bean的类名称,将来通过反射生成实例
    void setBeanClassName(@Nullable String var1);

    @Nullable
    String getBeanClassName();

    //设置bean的作用域
    void setScope(@Nullable String var1);

    @Nullable
    String getScope();

    //设置是否懒加载
    void setLazyInit(boolean var1);

    boolean isLazyInit();

    void setDependsOn(@Nullable String... var1);

    //返回bean的所有依赖
    @Nullable
    String[] getDependsOn();

    void setAutowireCandidate(boolean var1);

    //改bean是否可以注入到其它bean中
    boolean isAutowireCandidate();

    //主要的bean:统一接口的多个实现
    //如果不指定名字的话,Spring会优先选择设置Primary 为true的bean
    void setPrimary(boolean var1);

    boolean isPrimary();

    //如果改bean 采用工厂方法生成,指定工厂名
    //就是说,有些实例不是通过反射生成的,而是用工厂模式生成的
    void setFactoryBeanName(@Nullable String var1);

    @Nullable
    String getFactoryBeanName();

    void setFactoryMethodName(@Nullable String var1);

    @Nullable
    String getFactoryMethodName();

    ConstructorArgumentValues getConstructorArgumentValues();

    default boolean hasConstructorArgumentValues() {
        return !this.getConstructorArgumentValues().isEmpty();
    }

    //bean中的属性值
    MutablePropertyValues getPropertyValues();

    default boolean hasPropertyValues() {
        return !this.getPropertyValues().isEmpty();
    }
    void setInitMethodName(@Nullable String var1);

    @Nullable
    String getInitMethodName();
    void setDestroyMethodName(@Nullable String var1);
    @Nullable
    String getDestroyMethodName();
    void setRole(int var1);
    int getRole();
    void setDescription(@Nullable String var1);
    @Nullable
    String getDescription();
    ResolvableType getResolvableType();

    //是否 singleton
    boolean isSingleton();

    //是否prototype
    boolean isPrototype();

    //如果bean被设置为 abstract ,则不能实例化
    boolean isAbstract();

    @Nullable
    String getResourceDescription();
    @Nullable
    org.springframework.beans.factory.config.BeanDefinition getOriginatingBeanDefinition();
}

了解了 BeanDefinition 之后,我们再回到 refreshBeanFactory() 方法中接着分析 

加载 Bean: loadBeanDefinitions

这里加载bean的方法loadBeanDefinitions(beanFactory); 是重要的。这个方法根据配置,加载各个bean,然后放到BeanFactory中。
  loadBeanDefinitions()方法 通过一个实例 XmlBeanDefinitionReader 来加载各个bean
 读取配置的操作在 XmlBeanDefinitionReader 中,负责加载、配置、解析。

@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // Create a new XmlBeanDefinitionReader for the given BeanFactory.
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

    // Configure the bean definition reader with this context's
    // resource loading environment.
    beanDefinitionReader.setEnvironment(this.getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

    // Allow a subclass to provide custom initialization of the reader,
    // then proceed with actually loading the bean definitions.
    //初始化 beanDefinitionReader
    initBeanDefinitionReader(beanDefinitionReader);
    //重点
    //从此方法进入,哒哒哒一推 进入解析bean之路
    loadBeanDefinitions(beanDefinitionReader);
}

...

最后,<bean/>配置转换成一个个的 BeanDefinition ,然后注册各个 BeanDefinition 到注册中心,并且发送注册事件。

准备Bean容器 prepareBeanFactory()

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // Tell the internal bean factory to use the context's class loader etc.
    //设置BeanFactory 的类加载器
    //这里设置加载的是 ApplicationContext 类的类加载器
    beanFactory.setBeanClassLoader(getClassLoader());

    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    // Configure the bean factory with context callbacks.
    //添加一个 BeanPostProcessor :实现了 Aware 接口的bean在初始化时,这个Processor 负责回调
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

    // BeanFactory interface not registered as resolvable type in a plain factory.
    // MessageSource registered (and found for autowiring) as a bean.
    //为特殊的bean赋值
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    // Register early post-processor for detecting inner beans as ApplicationListeners.
    //注册事件监听器
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

    // Detect a LoadTimeWeaver and prepare for weaving, if found.
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        // Set a temporary ClassLoader for type matching.
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }

    /*
     * 下面的代码,就是体现Spring更智能的体现:
     * Spring会默认帮我们注册一些bean
     */
    // Register default environment beans.
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
}

初始化所有的 singleton beans

finishBeanFactoryInitialization() :负责初始化所有的 singleton beans。

回顾一下,到现在为止,BeanFactory 已经创建完成,并且所有实现了 BeanFactoryPostProcessor 接口的Bean都已经完成初始化,其中 postProcessorBeanFactory(factory) 方法也已经得到回调执行。Spring也已经“自动”注册了一些特殊的Bean。

OK!如果没有懒加载,接下来 Spring 就会初始化所有的 singleton beans。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // Initialize conversion service for this context.

    //初始化名为 conversionService的bean
    //初始化的动作被封装在beanFactory.getBean()中
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
            beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
        beanFactory.setConversionService(
                beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    }

    // Register a default embedded value resolver if no bean post-processor
    // (such as a PropertyPlaceholderConfigurer bean) registered any before:
    // at this point, primarily for resolution in annotation attribute values.
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
    }
    // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }
    // Stop using the temporary ClassLoader for type matching.
    beanFactory.setTempClassLoader(null);
    // Allow for caching all bean definition metadata, not expecting further changes.
    beanFactory.freezeConfiguration();

    // Instantiate all remaining (non-lazy-init) singletons.
    //开始初始化
    beanFactory.preInstantiateSingletons();
}

进入 开始初始化的方法中,会发现我们又回到了 DefaultListableBeanFactory 类中

preInstantiateSingletons()

public void preInstantiateSingletons() throws BeansException {
    if (this.logger.isTraceEnabled()) {
        this.logger.trace("Pre-instantiating singletons in " + this);
    }

    //保存了所有的beanNames
    List<String> beanNames = new ArrayList(this.beanDefinitionNames);
    Iterator var2 = beanNames.iterator();

    //下面这个循环,触发所有的非懒加载的 singleton beans 的初始化操作
    while(true) {
        String beanName;
        Object bean;
        do {
            while(true) {
                RootBeanDefinition bd;
                do {
                    do {
                        do {
                            if (!var2.hasNext()) {
                                var2 = beanNames.iterator();

                                while(var2.hasNext()) {
                                    beanName = (String)var2.next();
                                    Object singletonInstance = this.getSingleton(beanName);
                                    if (singletonInstance instanceof SmartInitializingSingleton) {
                                        SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
                                        if (System.getSecurityManager() != null) {
                                            AccessController.doPrivileged(() -> {
                                                smartSingleton.afterSingletonsInstantiated();
                                                return null;
                                            }, this.getAccessControlContext());
                                        } else {
                                            smartSingleton.afterSingletonsInstantiated();
                                        }
                                    }
                                }

                                return;
                            }

                            beanName = (String)var2.next();
                            bd = this.getMergedLocalBeanDefinition(beanName);
                        } while(bd.isAbstract());
                    } while(!bd.isSingleton());
                } while(bd.isLazyInit());

                //FactoryBean 在bean前面加上 & 符号再调用getBean()
                //FactoryBean 适用于创建过程比较复杂的场景,比如数据库连接池的创建
                if (this.isFactoryBean(beanName)) {
                    bean = this.getBean("&" + beanName);
                    break;
                }

                //对于一般的bean 直接调用getBean()方法 就可以进行初始化了
                this.getBean(beanName);
            }
        } while(!(bean instanceof FactoryBean));
        //到这里循环结束,说明所有的非懒加载的 singleton beans 已经完成了初始化
        
        FactoryBean<?> factory = (FactoryBean)bean;
        boolean isEagerInit;
        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
            SmartFactoryBean var10000 = (SmartFactoryBean)factory;
            ((SmartFactoryBean)factory).getClass();
            isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());
        } else {
            isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
        }

        if (isEagerInit) {
            this.getBean(beanName);
        }
    }
}

接着,我们就是getBean()方法了,我们经常在 BeanFactory 中获取一个Bean,而初始化的过程也封装在这个方法里。

...

参考来源:Spring IOC 容器源码分析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值