Spring源码分析系列二ioc加载过程

35次阅读

共计 16832 个字符,预计需要花费 43 分钟才能阅读完成。

  首先看一段代码,我们通过这段代码分析 ioc 的加载过程。

public static void main(String[] args) {ApplicationContext applicationContext = new AnnotationConfigApplicationContext( MainConfig.class);
    Person bean = applicationContext.getBean(Person.class);
    System.out.println(bean);

    String[] namesForType = applicationContext.getBeanNamesForType( Person.class);

    for (String name : namesForType) {System.out.println(name);
    }
}

  通过上面的代码,可以看到是通过 ApplicationContext 加载 ioc 容器的。下面我们来看一下 AnnotationConfigApplicationContext 执行的具体流程,主要分为下面几步:

  • 初始化一个空容器,容器中不包含任何 Bean 信息。
  • 为容器中注册一个要被处理的注解 Bean
  • 刷新容器
// 创建 ioc 容器
// 最常用的构造函数,通过将涉及到的配置类传递给该构造函数,以实现将相应配置类中的 Bean 自动注册到容器中
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {//1. 初始化一个空容器,容器不包含任何 Bean 信息,需要在稍后通过调用其 register() 方法注册配置类,并调用 refresh() 方法刷新容器,触发容器对注解 Bean 的载入、解析和注册过程
    this();
    //2. 为容器中注册一个要被处理的注解 Bean,新注册的 Bean,必须手动调用容器的 refresh() 方法刷新容器,触发容器对新注册的 Bean 的处理
    register(annotatedClasses);
    //3. 刷新容器
    refresh();}

附一张时序图,大家可以结合代码理解(图片来源网络)

1. 初始化一个空容器

// 默认构造函数,初始化一个空容器,容器不包含任何 Bean 信息,需要在稍后通过调用其 register() 方法注册配置类,并调用 refresh() 方法刷新容器,触发容器对注解 Bean 的载入、解析和注册过程
public AnnotationConfigApplicationContext() {this.reader = new AnnotatedBeanDefinitionReader(this);
    this.scanner = new ClassPathBeanDefinitionScanner(this);
}

2. 为容器注册一个要被处理的注解 Bean

// 为容器中注册一个要被处理的注解 Bean,新注册的 Bean,必须手动调用容器的 refresh() 方法刷新容器,触发容器对新注册的 Bean 的处理
public void register(Class<?>... annotatedClasses) {Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
    this.reader.register(annotatedClasses);
}

2.1 注册自定义注解 Bean

// 注册多个注解 Bean 自定义类
public void register(Class<?>... annotatedClasses) {for (Class<?> annotatedClass : annotatedClasses) {registerBean(annotatedClass);
    }
}

/**
 * Register a bean from the given bean class, deriving its metadata from
 * class-declared annotations.
 * @param annotatedClass the class of the bean
 */
// 注册一个注解 Bean 定义类
public void registerBean(Class<?> annotatedClass) {doRegisterBean(annotatedClass, null, null, null);
}

//Bean 定义读取器向容器注册注解 Bean 定义类
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
            @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {

    // 根据指定的注解 Bean 定义类,创建 Spring 容器中对注解 Bean 的封装的数据结构
    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {return;}

    abd.setInstanceSupplier(instanceSupplier);
    // 解析注解 Bean 定义的作用域,若 @Scope("prototype"),则 Bean 为原型类型;若 @Scope("singleton"),则 Bean 为单例类型
    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    // 为注解 Bean 定义设置作用域
    abd.setScope(scopeMetadata.getScopeName());
    // 为注解 Bean 定义生成 Bean 名称
    String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

    // 处理注解 Bean 定义中的通用注解
    AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
    // 如果在向容器注册注解 Bean 定义时,使用了额外的限定符注解,则解析限定符注解。主要是配置的关于 autowiring 自动依赖注入装配的限定条件,即 @Qualifier 注解
    //Spring 自动依赖注入装配默认是按类型装配,如果使用 @Qualifier 则按名称
    if (qualifiers != null) {for (Class<? extends Annotation> qualifier : qualifiers) {
            // 如果配置了 @Primary 注解,设置该 Bean 为 autowiring 自动依赖注入装配时的首选
            if (Primary.class == qualifier) {abd.setPrimary(true);
            }
            // 如果配置了 @Lazy 注解,则设置该 Bean 为非延迟初始化,如果没有配置,则该 Bean 为预实例化
            else if (Lazy.class == qualifier) {abd.setLazyInit(true);
            }
            // 如果使用了除了 @Primary 和 @Lazy 以外的其他注解,则为该 Bean 添加一个 autowiring 自动依赖注入装配限定符,该 Bean 在进 autowiring 自动依赖注入装配时,根据名称装配限定符指定的 Bean
            else {abd.addQualifier(new AutowireCandidateQualifier(qualifier));
            }
        }
    }
    for (BeanDefinitionCustomizer customizer : definitionCustomizers) {customizer.customize(abd);
    }
    // 创建一个指定 Bean 名称的 Bean 定义对象,封装直接 Bean 定义类数据
    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
        // 根据注解 Bean 定义类中配置的作用域,创建响应的代理对象
        definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    // 向 IOC 容器注册注解 Bean 类定义对象
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

3. 刷新容器

    @Override
    public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            // 刷新前的预处理
            //1、调用容器准备刷新的方法,获取容器的当前时间,同时给容器设置同步标识
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            // 初始化 BeanFactory
            //2. 告诉子类启动 refreshBeanFactory() 方法,Bean 定义资源文件的载入从子类的 refreshBeanFactory() 方法启动
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            //BeanFactory 的预准备工作
            //3、为 BeanFactory 配置容器特性,例如类加载器、事件处理器等
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                //BeanFactory 的后置处理器
                //4、为容器的某些子类指定特殊的 BeanPost 事件处理器
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                //5、调用所有注册的 BeanFactoryPostProcessor 的 Bean
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                //Bean 的后置处理器
                //6、为 BeanFactory 注册 BeanPost 事件处理器
                //BeanPostProcessor 是 Bean 后置处理器,用于监听容器触发的事件
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                //7、初始化信息源,和国际化相关
                initMessageSource();

                // Initialize event multicaster for this context.
                //8、初始化容器事件传播器
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                //9、调用子类的某些特殊 Bean 初始化方法
                onRefresh();

                // Check for listener beans and register them.
                //10、为事件传播器注册事件监听器
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                //11、初始化所有剩余的单例 Bean
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                //12、初始化容器的生命周期事件处理器,并发布容器的声明周期事件
                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.
                //13、销毁已创建的 Bean
                destroyBeans();

                // Reset 'active' flag.
                //14、取消 refresh 操作,重置容器的同步标识
                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...
                //15、重设公共缓存
                resetCommonCaches();}
        }
    }

3.1 调用容器准备刷新的方法,获取容器的当前时间,同时给容器设置同步标识(刷新前的预处理)

    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
        // 检查属性的合法性等
        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<>();}

3.2 告诉子类启动 refreshBeanFactory() 方法,Bean 定义资源文件的载入从子类的 refreshBeanFactory() 方法启动

    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        // 刷新【创建】BeanFactory
        // 这里使用了委派设计模式,父类定义了抽象的 refreshBeanFactory() 方法,具体实现调用子类容器的 refreshBeanFactory() 方法
        refreshBeanFactory();
        // 返回刚才 GenericApplicationContext 创建的 BeanFactory 对象
        // 将创建的 BeanFactory【DefaultListableBeanFactory】返回
        return getBeanFactory();}

3.2.1 刷新(创建)BeanFactory

    @Override
    protected final void refreshBeanFactory() throws IllegalStateException {if (!this.refreshed.compareAndSet(false, true)) {
            throw new IllegalStateException("GenericApplicationContext does not support multiple refresh attempts: just call'refresh'once");
        }
        this.beanFactory.setSerializationId(getId());
    }

3.2.2 返回刚才 GenericApplicationContext 创建的 BeanFactory 对象

    @Override
    public final ConfigurableListableBeanFactory getBeanFactory() {return this.beanFactory;}

3.3 为 BeanFactory 配置容器特性,例如类加载器、事件处理器等(BeanFactory 的预准备工作)

    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // Tell the internal bean factory to use the context's class loader etc.
        //1、设置 BeanFactory 的类加载器、支持表达式解析器
        beanFactory.setBeanClassLoader(getClassLoader());
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

        // Configure the bean factory with context callbacks.
        //2、添加部分 BeanPostProcessor【ApplicationContextAwareProcessor】beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        //3、设置忽略的自动装配的接口 EnvironmentAware、EmbeddedValueResolverAware、xxx
        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.
        //4、注册可以解析的自动装配:我们能直接在任何组件中自动注入:BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
        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.
        //5、添加 BeanPostProcessor【ApplicationListenerDetector】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()));
        }

        // 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());
        }
    }

3.4 为容器的某些子类指定特殊的 BeanPost 事件处理器

    @Override
    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {if (this.servletContext != null) {beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));
            beanFactory.ignoreDependencyInterface(ServletContextAware.class);
        }
        WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
        WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext);
    }

3.5 调用所有注册的 BeanFactoryPostProcessor 的 Bean

    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

        // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
        // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
        if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }
    }

3.6 为 BeanFactory 注册 BeanPost 事件处理器(Bean 的后置处理器)

    protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
    }

3.7 初始化信息,和国际化相关

    protected void initMessageSource() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
            // Make MessageSource aware of parent MessageSource.
            if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
                if (hms.getParentMessageSource() == null) {
                    // Only set parent context as parent MessageSource if no parent MessageSource
                    // registered already.
                    hms.setParentMessageSource(getInternalParentMessageSource());
                }
            }
            if (logger.isTraceEnabled()) {logger.trace("Using MessageSource [" + this.messageSource + "]");
            }
        }
        else {
            // Use empty MessageSource to be able to accept getMessage calls.
            DelegatingMessageSource dms = new DelegatingMessageSource();
            dms.setParentMessageSource(getInternalParentMessageSource());
            this.messageSource = dms;
            beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
            if (logger.isTraceEnabled()) {logger.trace("No'" + MESSAGE_SOURCE_BEAN_NAME + "'bean, using [" + this.messageSource + "]");
            }
        }
    }

3.8 初始化容器事件传播器

    protected void initApplicationEventMulticaster() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
            this.applicationEventMulticaster =
                    beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
            if (logger.isTraceEnabled()) {logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
            }
        }
        else {this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
            if (logger.isTraceEnabled()) {
                logger.trace("No'" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "'bean, using" +
                        "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
            }
        }
    }

3.9 调用子类的某些特殊 Bean 初始化方法

    @Override
    protected void onRefresh() {this.themeSource = UiApplicationContextUtils.initThemeSource(this);
    }

3.10 为事件传播器注册事件监听器

    protected void registerListeners() {
        // Register statically specified listeners first.
        for (ApplicationListener<?> listener : getApplicationListeners()) {getApplicationEventMulticaster().addApplicationListener(listener);
        }

        // Do not initialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let post-processors apply to them!
        String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
        for (String listenerBeanName : listenerBeanNames) {getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

        // Publish early application events now that we finally have a multicaster...
        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (earlyEventsToProcess != null) {for (ApplicationEvent earlyEvent : earlyEventsToProcess) {getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }
    }

3.11 初始化所有剩余的单例 Bean

    // 对配置了 lazy-init 属性的 Bean 进行预实例化处理
    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // Initialize conversion service for this context.
        // 这是 Spring3 以后新加的代码,为容器指定一个转换服务 (ConversionService)
        // 在对某些 Bean 属性进行转换时使用
        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.
        // 缓存容器中所有注册的 BeanDefinition 元数据,以防被修改
        beanFactory.freezeConfiguration();

        // Instantiate all remaining (non-lazy-init) singletons.
        // 对配置了 lazy-init 属性的单态模式 Bean 进行预实例化处理
        beanFactory.preInstantiateSingletons();}

3.12 初始化容器的生命周期事件处理器,并发布容器的声明周期事件

    protected void finishRefresh() {// Clear context-level resource caches (such as ASM metadata from scanning).
        clearResourceCaches();

        // Initialize lifecycle processor for this context.
        initLifecycleProcessor();

        // Propagate refresh to lifecycle processor first.
        getLifecycleProcessor().onRefresh();

        // Publish the final event.
        publishEvent(new ContextRefreshedEvent(this));

        // Participate in LiveBeansView MBean, if active.
        LiveBeansView.registerApplicationContext(this);
    }

3.13 销毁已创建的 Bean

    protected void destroyBeans() {getBeanFactory().destroySingletons();}

3.14 取消 refresh 操作,充值容器的同步标识

    @Override
    protected void cancelRefresh(BeansException ex) {this.beanFactory.setSerializationId(null);
        super.cancelRefresh(ex);
    }

3.15 重设公共缓存

    protected void resetCommonCaches() {ReflectionUtils.clearCache();
        AnnotationUtils.clearCache();
        ResolvableType.clearCache();
        CachedIntrospectionResults.clearClassLoader(getClassLoader());
    }

正文完
 0