Spring IoC源码:refresh都干了什么

本文详细解析了Spring框架中IoC容器的构建过程,从AnnotationConfigApplicationContext的构造方法入手,逐步深入到refresh方法的各个阶段,包括BeanFactory的初始化、BeanDefinition的解析、BeanPostProcessor的注册及Bean实例的创建。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

IoC 构建过程

首先是源码的入口之一AnnotationConfigApplicationContext

    public static void main(String[] args){
        AnnotationConfigApplicationContext annotationConfigApplicationContext =
                                            new AnnotationConfigApplicationContext(Config.class);
        User user = (User)annotationConfigApplicationContext.getBean("user");
        user.query();
    }

跟进去查看它的构造方法:

public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
    private final AnnotatedBeanDefinitionReader reader;
    private final ClassPathBeanDefinitionScanner scanner;

    public AnnotationConfigApplicationContext() {
        this.reader = new AnnotatedBeanDefinitionReader(this);
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }
    
    public AnnotationConfigApplicationContext(Class... annotatedClasses) {
        this();
        this.register(annotatedClasses);
        this.refresh();
    }
    ......
}

首先this()调用无参构造,调用父类的无参构造

public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
    private final DefaultListableBeanFactory beanFactory;
    @Nullable
    private ResourceLoader resourceLoader;
    private boolean customClassLoader;
    private final AtomicBoolean refreshed;

    public GenericApplicationContext() {
        this.customClassLoader = false;
        this.refreshed = new AtomicBoolean();
        this.beanFactory = new DefaultListableBeanFactory();
    }

    ......
}

这里创建了工厂(new DefaultListableBeanFactory()),这个DefaultListableBeanFactory是BeanFactory的一个实现类。之后我们将会用到它。

好了,在此之后我们进入重点refresh(),会调用父类 AbstractApplicationContext里的 refresh() 方法,这个方法就是构建整个 IoC 容器过程的完整代码,只要把这个方法里的每一行代码都了解了,基本上了解了大部分 Spring 的原理和功能。

refresh是一个模板方法,里面会调用12个方法。

@Override
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      // Prepare this context for refreshing.
      //准备此上下文以进行刷新
      prepareRefresh();

      // Tell the subclass to refresh the internal bean factory.
      //这里是在子类中启动refreshBeanFactort()的地方
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      // 准备bean工厂以在此上下文中使用。
      prepareBeanFactory(beanFactory);

      try {
         // Allows post-processing of the bean factory in context subclasses.
         // 允许在上下文子类中对bean工厂进行后处理。
         postProcessBeanFactory(beanFactory);

         // Invoke factory processors registered as beans in the context.
         //调用beanFactory的后处理器,这些后处理器是在bean定义中向容器注册的
         invokeBeanFactoryPostProcessors(beanFactory);

         // Register bean processors that intercept bean creation.
         // 注册bean的后处理器,在bean创建过程中调用
         registerBeanPostProcessors(beanFactory);

         // Initialize message source for this context.
         //对上下文中的消息源进行初始化
         initMessageSource();

         // Initialize event multicaster for this context.
         //初始化上下文中的事件机制
         initApplicationEventMulticaster();

         // Initialize other special beans in specific context subclasses.
         //初始化其他的特殊bean
         onRefresh();

         // Check for listener beans and register them.
         //检查监听bean并且将这些bean向容器注册
         registerListeners();

         // Instantiate all remaining (non-lazy-init) singletons.
         //实例化所有的(non-lazy-init)单利
         finishBeanFactoryInitialization(beanFactory);

         // Last step: publish corresponding event.
               //发布容器事件,结束refresh过程
         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.
         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...
               /**
                * 重置Spring核心中的常见内省缓存,
                * 从此我们开始可能再也不需要单例bean的元数据
                */
         resetCommonCaches();
      }
   }
}

1、startupShutdownMonitor 属性

用于“刷新”和“销毁”的同步监视器,说白了就是一个锁。

2、prepareRefresh() 方法

       为刷新准备新的 context,设置其启动日期和活动标志以及执行一些属性的初始化。主要是一些准备工作,不是很重要的方法,可以先不关注。

3、obtainFreshBeanFactory() 方法

用于获得一个新的 BeanFactory。

该方法会解析所有配置文件,加载所有 bean的定义,然后将这些 bean 的 beanName、beanName 和 bean 定义映射、beanName 和别名映射放到缓存中(beanDefinitionNames、beanDefinitionMap、aliasMap)。所有的 bean 相关的信息(bean的定义、初始化后的bean单例等等)和相关缓存都会放到 BeanFactory 中。

4、prepareBeanFactory(beanFactory) 方法

配置 beanFactory 的标准上下文特征,例如上下文的 ClassLoader、后置处理器等。这个方法会注册3个默认环境bean:environment、systemProperties 和 systemEnvironment,注册2个bean后置处理器:ApplicationContextAwareProcessor 和 ApplicationListenerDetector。

5、postProcessBeanFactory(beanFactory) 方法

允许在上下文子类中对 BeanFactory 进行后续处理,默认实现为空,留给子类实现。

6、invokeBeanFactoryPostProcessors(beanFactory) 方法

  • 1.实例化和调用所有已注册的 BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor。注:BeanDefinitionRegistryPostProcessor 继承自 BeanFactoryPostProcessor,主要用来在常规 BeanFactoryPostProcessor 检测开始之前注册其他 bean 定义。
  • 2.会将 beanDefinitionNames 缓存中的所有 bean 的合并的 BeanDefinition 创建出来,并放到 mergedBeanDefinitions 缓存。

注:Spring 中的 BeanFactoryPostProcessor 接口是 Spring 初始化 BeanFactory 时对外暴露的扩展点。

7、registerBeanPostProcessors(beanFactory) 方法

注册所有的 BeanPostProcessor,将所有实现了 BeanPostProcessor 接口的类加载到 BeanFactory 中。

8、initMessageSource() 方法

初始化 MessageSource。

9、initApplicationEventMulticaster() 方法

初始化 ApplicationEventMulticaster。

10、onRefresh() 方法

该方法为模板方法,提供给子类扩展实现,可以重写以添加特定于上下文的刷新工作,默认实现为空。

11、registerListeners() 方法

检查并注册监听器。

12、finishBeanFactoryInitialization(beanFactory) 方法

实例化所有剩余的 bean 实例(非懒加载)。除了一些内部的bean、实现了 BeanFactoryPostProcessor 的 bean、实现了 BeanPostProcessor 的 bean,其他的 bean 都会在这个 finishBeanFactoryInitialization 方法中被实例化。

13、finishRefresh() 方法

完成此 Context 的刷新,主要是推送上下文刷新完毕事件到监听器:ContextRefreshedEvent 。

其中,标红的是最为主要的方法。

下面看一看BeanDifinition和DefaultListableBeanFactory

BeanDifinition源码分析

        一个BeanDefinition描述了一个bean的实例,包括属性值,构造方法参数值和继承自它的类的更多信息。BeanDefinition仅仅是一个最简单的接口,主要功能是允许BeanFactoryPostProcessor 例如PropertyPlaceHolderConfigure 能够检索并修改属性值和别的bean的元数据(译注)。

        BeanDefinition接口用于描述一个bean实例的属性及构造参数等元数据;主要提供了父beanname,bean类型名,作用域,懒加载, bean依赖,自动注入候选bean,自动注入候选主要bean熟悉的设置与获取操作。同时提供了判断bean是否为单例、原型模式、抽象bean的操作,及获取bean的描述,资源描述,属性源,构造参数,原始bean定义等操作。最主的,BeanDefinition对Bean的配置信息进行了封装。

下面来看这个接口为其子类都提供了哪些具体的行为方法:

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

        /**
         * 这两个参数应该一看就明白了,singleton和prototype,这个可以看出spring默认提供这两种模式
         */
        String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
        String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
        /**
         * 表示一个应用的主要组成部分,比如一个用户定义的bean。
         */
        int ROLE_APPLICATION = 0;
        /**
         * - 表示一个支持一些比较大的配置的bean定义,如一个外部的组件定义
         */
        int ROLE_SUPPORT = 1;
        /**
         * - 表示一个内部使用的注册的bean组件定义,与终端用户无关。
         */
        int ROLE_INFRASTRUCTURE = 2;

        //attributes元素

        /**
         * - 设置bean定义的父name,如果有的话。
         */
        void setParentName(@Nullable String parentName);

        /**
         * 获取bean定义的父name,如果有的话
         */
        @Nullable
        String getParentName();

        /**
         * 设置bean定义的bean class name。在bean工厂后处理的过程中,类名可以被修改,典型的情况下
         * 将原始class的name,替换成一个可解析的变量。
         */
        void setBeanClassName(@Nullable String beanClassName);

        /**
         * 获取bean的class name 对应class的:class="spring.service.impl.MessageServiceImpl"
         */
        @Nullable
        String getBeanClassName();

        ······
    }

DefaultListableBeanFactory

BeanDefinition会放到DefaultListableBeanFactory的beanDefinitionMap中。beanDefinitionMap的key为Bean的名称,value为BeanDefinition。

package org.springframework.beans.factory.support;

@SuppressWarnings("serial")
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
        implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {

    private static Class<?> javaxInjectProviderClass = null;

    static {
        try {
            javaxInjectProviderClass =
                    ClassUtils.forName("javax.inject.Provider", DefaultListableBeanFactory.class.getClassLoader());
        }
        catch (ClassNotFoundException ex) {
            // JSR-330 API not available - Provider interface simply not supported then.
        }
    }


    /** 序列化ID映射到工厂实例的Map:Map from serialized id to factory instance */
    private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories =
            new ConcurrentHashMap<>(8);

    /** 可选ID,用于序列化:Optional id for this factory, for serialization purposes */
    private String serializationId;

    /** Whether to allow re-registration of a different definition with the same name */
    /** 是否允许同名字不同定义的bean重新注册*/
    private boolean allowBeanDefinitionOverriding = true;

    /** Whether to allow eager class loading even for lazy-init beans */
    /** 是否允许bean基至是延迟加载的bean马上加载*/
    private boolean allowEagerClassLoading = true;

    /** Optional OrderComparator for dependency Lists and arrays */
    /** 可选的用于依赖集合和数组的比较器*/
    private Comparator<Object> dependencyComparator;

    /** Resolver to use for checking if a bean definition is an autowire candidate */
    /** 用于检查一个类定义是否有自动注入请求的解析器*/
    private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();

    /** Map from dependency type to corresponding autowired value */
    /** 依赖类型到对应的注入值的映射*/
    private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);

    /** Map of bean definition objects, keyed by bean name */
    /** bean定义名字到bean定义数据实体的映射*/
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

    /** Map of singleton and non-singleton bean names, keyed by dependency type */
    /** 依赖类型到对应bean名字的映射,包括单例和非单例*/
    private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);

    /** Map of singleton-only bean names, keyed by dependency type */
    /** 依赖类型到对应bean名字的映射,仅包含单例*/
    private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);

    /** List of bean definition names, in registration order */
    /** 所有bean定义的名字的集合,按注册次序*/
    private volatile List<String> beanDefinitionNames = new ArrayList<>(256);

    /** List of names of manually registered singletons, in registration order */
    /** 手工注册的单例bean定义的名字的集合,按注册次序*/
    private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);

    /** Cached array of bean definition names in case of frozen configuration */
    /** 缓存bean定义名字的数组*/
    private volatile String[] frozenBeanDefinitionNames;

    /** Whether bean definition metadata may be cached for all beans */
    /** 是否允许bean定义的元数据被缓存,以用于所有的bean*/
    private volatile boolean configurationFrozen = false;


    /**
     * Create a new DefaultListableBeanFactory.
     */
    public DefaultListableBeanFactory() {
        super();
    }

    /**
     * Create a new DefaultListableBeanFactory with the given parent.
     * @param parentBeanFactory the parent BeanFactory
     */
    public DefaultListableBeanFactory(BeanFactory parentBeanFactory) {
        super(parentBeanFactory);
    }


    /**
     * Specify an id for serialization purposes, allowing this BeanFactory to be
     * 指定一个ID用于序列化操作,如有需要允许这个BeanFactory通过这个ID反序化为此BeanFactory对象
     * deserialized from this id back into the BeanFactory object, if needed.
     */
    public void setSerializationId(String serializationId) {
        if (serializationId != null) {
            serializableFactories.put(serializationId, new WeakReference<>(this));
        }
        else if (this.serializationId != null) {
            serializableFactories.remove(this.serializationId);
        }
        this.serializationId = serializationId;
    }

    /**
     * Return an id for serialization purposes, if specified, allowing this BeanFactory
     * to be deserialized from this id back into the BeanFactory object, if needed.
     * @since 4.1.2
     */
    public String getSerializationId() {
        return this.serializationId;
    }

    /**
     * Set whether it should be allowed to override bean definitions by registering
     * a different definition with the same name, automatically replacing the former.
     * If not, an exception will be thrown. This also applies to overriding aliases.
     * <p>Default is "true".
     * @see #registerBeanDefinition
     */
    public void setAllowBeanDefinitionOverriding(boolean allowBeanDefinitionOverriding) {
        this.allowBeanDefinitionOverriding = allowBeanDefinitionOverriding;
    }

    /**
     * Return whether it should be allowed to override bean definitions by registering
     * a different definition with the same name, automatically replacing the former.
     * @since 4.1.2
     */
    public boolean isAllowBeanDefinitionOverriding() {
        return this.allowBeanDefinitionOverriding;
    }

    /**
     * Set whether the factory is allowed to eagerly load bean classes
     * 设置该工厂是否被允许马上加载bean定义
     * even for bean definitions that are marked as "lazy-init".
     * 即使是被标记为延迟加载的bean定义
     * <p>Default is "true". Turn this flag off to suppress class loading
     * for lazy-init beans unless such a bean is explicitly requested.
     * 如果有明确的要求,可以关闭这个标志以阻止延迟加载的类加载
     * In particular, by-type lookups will then simply ignore bean definitions
     * without resolved class name, instead of loading the bean classes on
     * demand just to perform a type check.
     * 尤其是by-type查找的时候总是忽略bean的这此定义,不解析类名,而是根据需要加载bean仅仅是完成一个类型检查
     * @see AbstractBeanDefinition#setLazyInit
     */
    public void setAllowEagerClassLoading(boolean allowEagerClassLoading) {
        this.allowEagerClassLoading = allowEagerClassLoading;
    }

    /**
     * Return whether the factory is allowed to eagerly load bean classes
     * even for bean definitions that are marked as "lazy-init".
     * @since 4.1.2
     */
    public boolean isAllowEagerClassLoading() {
        return this.allowEagerClassLoading;
    }

    /**
     * Set a {@link java.util.Comparator} for dependency Lists and arrays.
     * @see org.springframework.core.OrderComparator
     * @see org.springframework.core.annotation.AnnotationAwareOrderComparator
     */
    public void setDependencyComparator(Comparator<Object> dependencyComparator) {
        this.dependencyComparator = dependencyComparator;
    }

    /**
     * Return the dependency comparator for this BeanFactory (may be {@code null}.
     */
    public Comparator<Object> getDependencyComparator() {
        return this.dependencyComparator;
    }

    /**
     * Set a custom autowire candidate resolver for this BeanFactory to use
     * when deciding whether a bean definition should be considered as a
     * candidate for autowiring.
     * 给这个工厂设置一个定制的自动注入请求解析器,以便当决定是否一个bean的定义可以考虑为自动注入请求时使用
     */
    public void setAutowireCandidateResolver(final AutowireCandidateResolver autowireCandidateResolver) {
        Assert.notNull(autowireCandidateResolver, "AutowireCandidateResolver must not be null");
        if (autowireCandidateResolver instanceof BeanFactoryAware) {
            if (System.getSecurityManager() != null) {
                final BeanFactory target = this;
                AccessController.doPrivileged(new PrivilegedAction<Object>() {
                    @Override
                    public Object run() {
                        ((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(target);
                        return null;
                    }
                }, getAccessControlContext());
            }
            else {
                ((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(this);
            }
        }
        this.autowireCandidateResolver = autowireCandidateResolver;
    }

    /**
     * Return the autowire candidate resolver for this BeanFactory (never {@code null}).
     */
    public AutowireCandidateResolver getAutowireCandidateResolver() {
        return this.autowireCandidateResolver;
    }


    @Override
    public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) {
        super.copyConfigurationFrom(otherFactory);
        if (otherFactory instanceof DefaultListableBeanFactory) {
            DefaultListableBeanFactory otherListableFactory = (DefaultListableBeanFactory) otherFactory;
            this.allowBeanDefinitionOverriding = otherListableFactory.allowBeanDefinitionOverriding;
            this.allowEagerClassLoading = otherListableFactory.allowEagerClassLoading;
            this.autowireCandidateResolver = otherListableFactory.autowireCandidateResolver;
            this.resolvableDependencies.putAll(otherListableFactory.resolvableDependencies);
        }
    }
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值