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

2019-09-28 00:00:00 分析 系列 源码

  首先看一段代码,我们通过这段代码分析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();
}

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

《Spring源码分析系列(二)--ioc加载过程》

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());
    }
    原文作者:时光无声
    原文地址: https://segmentfault.com/a/1190000020518592
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。

相关文章