zoukankan      html  css  js  c++  java
  • spring 学习-bean创建-refresh方法

    前言

    要是一上来就看 refresh 方法容易绕晕 , 再看源码之前 , 大家可以先去了解一下 context 和 beanFactory 的功能作用.

    概述

    上一节我们通过注解的方式将扫描到的 bean 信息都放在了 context 中了 ,那么本节我们开始介绍 refresh 方法。该方法也是生成 bean 的重要方法。 上一节我们讲到 :

    	public AnnotationConfigApplicationContext(DefaultListableBeanFactory beanFactory) {
    		super(beanFactory);
    		this.reader = new AnnotatedBeanDefinitionReader(this);
    		this.scanner = new ClassPathBeanDefinitionScanner(this);
    	}
    
    	/**
    	 * Create a new AnnotationConfigApplicationContext, deriving bean definitions
    	 * from the given component classes and automatically refreshing the context.
    	 * @param componentClasses one or more component classes — for example,
    	 * {@link Configuration @Configuration} classes
    	 */
    	public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    		this();
    		register(componentClasses);
    		refresh();
    	}
    
    	/**
    	 * Create a new AnnotationConfigApplicationContext, scanning for components
    	 * in the given packages, registering bean definitions for those components,
    	 * and automatically refreshing the context.
    	 * @param basePackages the packages to scan for component classes
    	 */
    	public AnnotationConfigApplicationContext(String... basePackages) {
    		this();
    		scan(basePackages);
    		refresh();
    	}
    
    

    构造方法最后都会走到 refresh 方法 , 我依然要放出这张图, 该图有利于理解我们了解spring 生成 bean 的过程 。我们知道 bean 可以通过 xml 文件方式注入 , 也可以通过注解的方式注入 , 下面是 AnnotationConfigApplicationContextClassPathXmlApplicationContext 两个类的继承结构图 , 可以看到 AbstractApplicationContext 这个可以说是逻辑抽象类 , 从文章后边讲的 refresh 方法也可以知道.

    1297993-20210802232732542-1356689512.png

    1297993-20210802232756810-429752981.png

    而 AbstractApplicationContext 中有个 抽象方法返回一个 ConfigurableListableBeanFactory 对象 , 这个对象的作用是对类的管理和初始化. 我们甚至可以说 context 类是集大成者 , 而 beanFactory 从名字也可以看出是bean 相关的管家 .

    划重点 :

    1. context 类是集大成者
    2. beanFactory 从名字也可以看出是bean 相关的管家 .

    记住这两点有助于我们学习 生成 bean 的过程 , 不然容易被后面的逻辑绕晕.

    refresh 方法

    refresh 方法不是 AnnotationConfigApplicationContext 类的方法 ,而是父类的方法 , 位于org.springframework.context.support.AbstractApplicationContext#refresh

    
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();
    
            // Tell the subclass to refresh the internal bean factory.
    		// 这个 beanFactory 对象很重要 , 后面很多 bean 逻辑都是在这个类完成的. 
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);
    
            try {
                // Allows post-processing of the bean factory in context subclasses.
                //在 context 的子类实现,父类方法为空方法
                postProcessBeanFactory(beanFactory);
    
                // Invoke factory processors registered as beans in the context.
                //  实例化 并 执行 之前已经注册了的各种 BeanFactoryPostProcessor
                invokeBeanFactoryPostProcessors(beanFactory);
    
                // Register bean processors that intercept bean creation.
    			//这里的注册,是指把实例化的BeanPostProcessor存到beanFactory的某个list中
                registerBeanPostProcessors(beanFactory);
    
                // Initialize message source for this context.
                initMessageSource();
    
                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();
    
                // Initialize other special beans in specific context subclasses.
                // 空方法子类实现
                onRefresh();
    
                // Check for listener beans and register them.
                // 检查 listener 并注册他们
                registerListeners();
    
                // Instantiate all remaining (non-lazy-init) singletons.
                // 初始化剩下的单例类 
                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.
                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();
            }
        }
    }
    

    可以看到 refresh 方法不长 ,但是每个方法调用下去很容易绕晕, 我们先总结一下 refresh 主要做了什么事吧

    1. 前期准备;记录了容器启动时间;容器状态;刷新一些在此方法之前就可能已经存在的监听器
    2. 空方法,用于子类扩展功能
    3. 实例化并执行之前已经注册了的各种BeanFactoryPostProcessor (核心)
    4. 实例化 拦截bean创建的处理器BeanPostProcessor;(核心)
    5. 初始化容器的MessageSource类型的bean,MessageSource用于解析消息
    6. 初始化容器的事件广播
    7. 空方法,在特定的子类中 初始化其他特殊bean
    8. 注册实现了ApplicationListener接口的监听者
    9. 实例化剩下的单例bean,完成全部bean的实例化,除了懒加载的 (核心)
    10. 最后一步,完成此刷新方法,发布完成事件

    我们浓缩一下和 bean 相关的最核心的重要步骤 :

    1. 实例化执行 之前已经注册了的各种 BeanFactoryPostProcessor
    2. 调用 getBean 方法

    还有一点大家需要注意的是我们看到refresh 中调用的方法都会把 beanFactory 传过去 , 足以说明了 beanFactory 的功能和重要性 !!!

    prepareRefresh

    org.springframework.context.support.AbstractApplicationContext#prepareRefresh

    	/**
    	 * Prepare this context for refreshing, setting its startup date and
    	 * active flag as well as performing any initialization of property sources.
    	 */
    	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<>();
    	}
    
    • 设置Spring容器的启动时间,
    • 开启活跃状态,撤销关闭状态,。
    • 初始化context environment(上下文环境)中的占位符属性来源。
    • 验证环境信息里一些必须存在的属性

    obtainFreshBeanFactory

    			// Tell the subclass to refresh the internal bean factory.
    			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    

    这一行代码 , 需要注意一下 , obtainFreshBeanFactory 这个方法会返回一个 ConfigurableListableBeanFactory 对象 , 该对象继承 BeanFactory , 而实际上 Context 关于 Bean 相关的逻辑都是 BeanFactory 来完成 .

    	/**
    	 * Tell the subclass to refresh the internal bean factory.
    	 * @return the fresh BeanFactory instance
    	 * @see #refreshBeanFactory()
    	 * @see #getBeanFactory()
    	 */
    	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    		refreshBeanFactory();
    		return getBeanFactory();
    	}
    
    
    
    	/**
    	 * Subclasses must return their internal bean factory here. They should implement the
    	 * lookup efficiently, so that it can be called repeatedly without a performance penalty.
    	 * <p>Note: Subclasses should check whether the context is still active before
    	 * returning the internal bean factory. The internal factory should generally be
    	 * considered unavailable once the context has been closed.
    	 * @return this application context's internal bean factory (never {@code null})
    	 * @throws IllegalStateException if the context does not hold an internal bean factory yet
    	 * (usually if {@link #refresh()} has never been called) or if the context has been
    	 * closed already
    	 * @see #refreshBeanFactory()
    	 * @see #closeBeanFactory()
    	 */
    	@Override
    	public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
    
    
    

    prepareBeanFactory

    我们得到的 BeanFactory 需要初始化很多参数 , 包括 BPP (BeanPostProcessor)

    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    	//设置BeanFactory的类加载器
    	// Tell the internal bean factory to use the context's class loader etc.
    	beanFactory.setBeanClassLoader(getClassLoader());
    	//设置支持表达式解析器
    	beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    	beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    	
        //添加部分BeanPostProcessor【ApplicationContextAwareProcessor】, 回调
    	// Configure the bean factory with context callbacks.
    	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.
            //注册可以解析的自动装配;我们能直接在任何组件中自动注入:BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
            //其他组件中可以通过 @autowired 直接注册使用
    	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.
        // 添加部分BeanPostProcessor【ApplicationListenerDetector】,作用: 发现早期内部的 bean 
    	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.
        // 注册默认的环境 beans , 可以看到是先会去判断是否是 beanFactory 本身创建的 bean ,例如 springboot 中我们有些场景下会去使用使用自己的 bean  ,而不是默认的 environment bean ,不存在再去注册 
    	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());
    	}
    }
    
    

    postProcessBeanFactory

    空方法 , 子类实现

    	/**
    	 * Modify the application context's internal bean factory after its standard
    	 * initialization. All bean definitions will have been loaded, but no beans
    	 * will have been instantiated yet. This allows for registering special
    	 * BeanPostProcessors etc in certain ApplicationContext implementations.
    	 * @param beanFactory the bean factory used by the application context
    	 */
    	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    	}
    
    

    invokeBeanFactoryPostProcessors

    
        /**
         * 注意哦,这里传进来的 beanFactoryPostProcessors 是来自 AbstractApplicationContext , 
         * 该方法会调用 所有的 BeanFactoryPostProcessor 的回调方法,回调方法指的是 BeanPostProcessor 的接口的接口方法(用于回调)  
         */
    	public static void invokeBeanFactoryPostProcessors(
    			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
    		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
    		Set<String> processedBeans = new HashSet<>();
    
    		if (beanFactory instanceof BeanDefinitionRegistry) {
    			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
    			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
    			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
    
    
                //先处理 BeanDefinitionRegistryPostProcessor 
    			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
    				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
    					BeanDefinitionRegistryPostProcessor registryProcessor =
    							(BeanDefinitionRegistryPostProcessor) postProcessor;
    					registryProcessor.postProcessBeanDefinitionRegistry(registry);
    					registryProcessors.add(registryProcessor);
    				}
    				else {
    					regularPostProcessors.add(postProcessor);
    				}
    			}
    
    			// Do not initialize FactoryBeans here: We need to leave all regular beans
    			// uninitialized to let the bean factory post-processors apply to them!
    			// Separate between BeanDefinitionRegistryPostProcessors that implement
    			// PriorityOrdered, Ordered, and the rest.
    
    			// 翻译上边:这里先不初始化FactoryBeans,我们需要保留所有常规bean的状态为非初始化状态,好让post-processors能对它们发挥作用
    			//实现了PriorityOrdered, Ordered或者其他接口的,要分开处理。
    
    			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
    
    
    
    
    			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
    			String[] postProcessorNames =
    					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    			for (String ppName : postProcessorNames) {
    				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    					processedBeans.add(ppName);
    				}
    			}
    			sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                //该方法最终会调用  BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry 接口方法,该方法就是执行后置器的逻辑,例如 ConfigurationClassPostProcessor 的 postProcessBeanDefinitionRegistry 处理配置bean 的逻辑,我们在后续再分析 
    			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
    			currentRegistryProcessors.clear();
    
    			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
    			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    			for (String ppName : postProcessorNames) {
    				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
    					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    					processedBeans.add(ppName);
    				}
    			}
    			sortPostProcessors(currentRegistryProcessors, beanFactory);
    			registryProcessors.addAll(currentRegistryProcessors);
    			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
    			currentRegistryProcessors.clear();
    
                //在这个处理过程中,可能会有新的bean被spring发现,并注册到容器中。
                // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
    			boolean reiterate = true;
    			while (reiterate) {
    				reiterate = false;
    				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    				for (String ppName : postProcessorNames) {
    					if (!processedBeans.contains(ppName)) {
    						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    						processedBeans.add(ppName);
    						reiterate = true;
    					}
    				}
    				sortPostProcessors(currentRegistryProcessors, beanFactory);
    				registryProcessors.addAll(currentRegistryProcessors);
    				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
    				currentRegistryProcessors.clear();
    			}
    
                // 调用剩下没有调用过的 processors 的回调方法 
    			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
    			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
    			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    		}
    
    		else {
    			// Invoke factory processors registered with the context instance.
    			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    		}
    
    		// Do not initialize FactoryBeans here: We need to leave all regular beans
    		// uninitialized to let the bean factory post-processors apply to them!
    		String[] postProcessorNames =
    				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    
    		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
    		// Ordered, and the rest.
    		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    		List<String> orderedPostProcessorNames = new ArrayList<>();
    		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    		for (String ppName : postProcessorNames) {
    			if (processedBeans.contains(ppName)) {
    				// skip - already processed in first phase above
    			}
    			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
    			}
    			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
    				orderedPostProcessorNames.add(ppName);
    			}
    			else {
    				nonOrderedPostProcessorNames.add(ppName);
    			}
    		}
    
    		// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
    		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
    		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
    		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    		for (String postProcessorName : orderedPostProcessorNames) {
    			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    		}
    		sortPostProcessors(orderedPostProcessors, beanFactory);
    		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    
    		// Finally, invoke all other BeanFactoryPostProcessors.
    		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    		for (String postProcessorName : nonOrderedPostProcessorNames) {
    			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    		}
    		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    
    		// Clear cached merged bean definitions since the post-processors might have
    		// modified the original metadata, e.g. replacing placeholders in values...
    		beanFactory.clearMetadataCache();
        }
    

    重点看一下 PostProcessorRegistrationDelegate 的 invokeBeanFactoryPostProcessors 静态方法 。

    BeanFactoryPostProcessor总共有两种:

    1.BeanFactoryPostProcessor

    2.BeanDefinitionRegistryPostProcessor,它继承了第一种。

    整体上流程如下:

    1. 处理BeanDefinitionRegistryPostProcessor

    1.1 处理PriorityOrdered优先级的

    1.2 处理Ordered优先级的

    1.3 处理其他优先级的

    1. 处理BeanFactoryPostProcessor

    2.1 处理PriorityOrdered优先级的

    2.2 处理Ordered优先级的

    2.3 处理其他优先级的

    题外话 -- BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessors

    public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
    
    	/**
    	 * Modify the application context's internal bean definition registry after its
    	 * standard initialization. All regular bean definitions will have been loaded,
    	 * but no beans will have been instantiated yet. This allows for adding further
    	 * bean definitions before the next post-processing phase kicks in.
    	 * 
    	 * 作用 : This allows for adding further
    	 * bean definitions (bean 定义) before the next post-processing phase kicks in
    	 * 
    	 * @param registry the bean definition registry used by the application context
    	 * @throws org.springframework.beans.BeansException in case of errors
    	 */
    	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
    
    }
    

    BeanDefinitionRegistryPostProcessor 继承 BeanFactoryPostProcessor , 我找了了它的一个实现类, org.springframework.context.annotation.ConfigurationClassPostProcessor , 最终会调用以下方法 ,作用是解析带有`@Configuration 的类

    /**
    	 * Build and validate a configuration model based on the registry of
    	 * {@link Configuration} classes.
    	 */
    	public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
    		
    
            ....
    
    		// Parse each @Configuration class
    
    		ConfigurationClassParser parser = new ConfigurationClassParser(
    				this.metadataReaderFactory, this.problemReporter, this.environment,
    				this.resourceLoader, this.componentScanBeanNameGenerator, registry);
    
    		Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
    		Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
    		do {
    			StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
    			parser.parse(candidates);
    			parser.validate();
    
    			Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
    			configClasses.removeAll(alreadyParsed);
    
    
    			// 看这里 !!!! 读取 model , 根据内容创建对应的 bean d
    			// Read the model and create bean definitions based on its content
    			if (this.reader == null) {
    				this.reader = new ConfigurationClassBeanDefinitionReader(
    						registry, this.sourceExtractor, this.resourceLoader, this.environment,
    						this.importBeanNameGenerator, parser.getImportRegistry());
    			}
    			this.reader.loadBeanDefinitions(configClasses);
    			alreadyParsed.addAll(configClasses);
    			processConfig.tag("classCount", () -> String.valueOf(configClasses.size())).end();
    
    			candidates.clear();
    			if (registry.getBeanDefinitionCount() > candidateNames.length) {
    				String[] newCandidateNames = registry.getBeanDefinitionNames();
    				Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
    				Set<String> alreadyParsedClasses = new HashSet<>();
    				for (ConfigurationClass configurationClass : alreadyParsed) {
    					alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
    				}
    				for (String candidateName : newCandidateNames) {
    					if (!oldCandidateNames.contains(candidateName)) {
    						BeanDefinition bd = registry.getBeanDefinition(candidateName);
    						if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
    								!alreadyParsedClasses.contains(bd.getBeanClassName())) {
    							candidates.add(new BeanDefinitionHolder(bd, candidateName));
    						}
    					}
    				}
    				candidateNames = newCandidateNames;
    			}
    		}
    		while (!candidates.isEmpty());
    
    
    
    		// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
    		
            if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
    			sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
    		}
    
    		if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
    			// Clear cache in externally provided MetadataReaderFactory; this is a no-op
    			// for a shared cache since it'll be cleared by the ApplicationContext.
    			((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
    		}
    	}
    
    

    registerBeanPostProcessors

    位置 : PostProcessorRegistrationDelegate#registerBeanPostProcessors BeanPostProcessor的作用是拦截bean创建,也就是在bean实例化的时候(实例化前后),能插入一些额外的动作 , 有点像拦截器的作用 .

    	public static void registerBeanPostProcessors(
    			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
    
    		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    
            //实例化一个BeanPostProcessorChecker,用于记录日志信息,比如当一个bean没有被任何后置处理器处理时
    	    //BeanPostProcessorChecker是一个内部类,实现了BeanPostProcessor接口
    		// Register BeanPostProcessorChecker that logs an info message when
    		// a bean is created during BeanPostProcessor instantiation, i.e. when
    		// a bean is not eligible for getting processed by all BeanPostProcessors.
    		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
    
    
    
    	    //这里也分为PriorityOrdered,Ordered, and 其他 3中情况分开处理;所以先遍历一遍,把类型分开;
    	    //遍历时候,顺便把PriorityOrdered实例化了
    		// Separate between BeanPostProcessors that implement PriorityOrdered,
    		// Ordered, and the rest.
            List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
            //内部使用的 PostProcessors 
    		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
            List<String> orderedPostProcessorNames = new ArrayList<>();
            //没有顺序的 PostProcessors
    		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    		for (String ppName : postProcessorNames) {
    			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
    				priorityOrderedPostProcessors.add(pp);
    				if (pp instanceof MergedBeanDefinitionPostProcessor) {
    					internalPostProcessors.add(pp);
    				}
    			}
    			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
    				orderedPostProcessorNames.add(ppName);
    			}
    			else {
    				nonOrderedPostProcessorNames.add(ppName);
    			}
    		}
    
    		// First, register the BeanPostProcessors that implement PriorityOrdered.
    		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
    
    		// Next, register the BeanPostProcessors that implement Ordered.
    		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    		for (String ppName : orderedPostProcessorNames) {
    			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
    			orderedPostProcessors.add(pp);
    			if (pp instanceof MergedBeanDefinitionPostProcessor) {
    				internalPostProcessors.add(pp);
    			}
    		}
    		sortPostProcessors(orderedPostProcessors, beanFactory);
    		registerBeanPostProcessors(beanFactory, orderedPostProcessors);
    
    		// Now, register all regular BeanPostProcessors.
    		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    		for (String ppName : nonOrderedPostProcessorNames) {
    			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
    			nonOrderedPostProcessors.add(pp);
    			if (pp instanceof MergedBeanDefinitionPostProcessor) {
    				internalPostProcessors.add(pp);
    			}
    		}
    		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
    
    		// Finally, re-register all internal BeanPostProcessors.
    		sortPostProcessors(internalPostProcessors, beanFactory);
    		registerBeanPostProcessors(beanFactory, internalPostProcessors);
    
    
    		// Re-register post-processor for detecting inner beans as ApplicationListeners,
            // moving it to the end of the processor chain (for picking up proxies etc).
            // 当前的 PostPocessors 见下图,这里重新注册 post-processor 作为 ApplicationListeners 用于发现内部的 beans
            // 放在 processor 处理端的尾部 , 用于获取代理等. 
    		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    	}
    
    
    
    /**
    	 * Register the given BeanPostProcessor beans. 
    	 */
    	private static void registerBeanPostProcessors(
    			ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
    
    		if (beanFactory instanceof AbstractBeanFactory) {
    			// Bulk addition is more efficient against our CopyOnWriteArrayList there
    			((AbstractBeanFactory) beanFactory).addBeanPostProcessors(postProcessors);
    		}
    		else {
    			for (BeanPostProcessor postProcessor : postProcessors) {
    				beanFactory.addBeanPostProcessor(postProcessor);
    			}
    		}
    	}
    
    
    	public void addBeanPostProcessors(Collection<? extends BeanPostProcessor> beanPostProcessors) {
    		this.beanPostProcessors.removeAll(beanPostProcessors);
    		this.beanPostProcessors.addAll(beanPostProcessors);
    	}
    

    可以看到注册 BeanPostProcessors 的逻辑主要就是加入到一个列表中去.

    initMessageSource

    MessageSource用于解析消息 , 提供了若干获取消息的方法 .

    
    /**
    Strategy interface for resolving messages, with support for the parameterization and internationalization of such messages.
    Spring provides two out-of-the-box implementations for production:
    
    1. org.springframework.context.support.ResourceBundleMessageSource: built on top of the standard java.util.ResourceBundle, sharing its limitations.
    
    2. org.springframework.context.support.ReloadableResourceBundleMessageSource: highly configurable, in particular with respect to reloading message definitions.
    
    **/
    
    public interface MessageSource {
    
    	@Nullable
    	String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale);
    
    	String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException;
    
    
    	String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
    
    }
    
    
    

    可以从接口的注释看到 MessageSource 是一个用于可以对信息国际化和参数化的接口 . spring 提供了 两个开箱即用的现实 : ResourceBundleMessageSourceReloadableResourceBundleMessageSource

    /**
    	 * Initialize the MessageSource.
    	 * Use parent's if none defined in this context.
    	 */
    	protected void initMessageSource() {
            // getBeanFactory 是个抽象方法 , 这个方法太秒了 !!! 剧透一下我们下一节就可以讲到真正获取 bean 的地方 , 其中就会需要
            // 一个 ConfigurableListableBeanFactory 对象 ,而这个对象就是由 这个抽象方法返回的! 我们下一节再讲 . 
    		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
            // 当前的这个 beanFactory 是否包含这么一个 MessageSource , 没有就创建咯
    		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 + "]");
    			}
    		}
    	}
    
    

    getBeanFactory 方法对获取 bean 非常重要 ,我们将会在下一节进行介绍 .

    initApplicationEventMulticaster

    从名字就可以知道是初始化事件广播.

    	/**
    	 * Initialize the ApplicationEventMulticaster.
    	 * Uses SimpleApplicationEventMulticaster if none defined in the context.
    	 * @see org.springframework.context.event.SimpleApplicationEventMulticaster
    	 */
    	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() + "]");
    			}
    		}
    	}
    

    代码也没高深的逻辑 , 和 initMessageSource 方法很像.

    onRefresh

    	/**
    	 * Template method which can be overridden to add context-specific refresh work.
    	 * Called on initialization of special beans, before instantiation of singletons.
    	 * <p>This implementation is empty.
    	 * @throws BeansException in case of errors
    	 * @see #refresh()
    	 */
    	protected void onRefresh() throws BeansException {
    		// For subclasses: do nothing by default.
    	}
    

    当前类为空方法 , 具体逻辑交给子类实现 .

    registerListeners

    注册监听事件

    	/**
    	 * Add beans that implement ApplicationListener as listeners.
    	 * Doesn't affect other listeners, which can be added without being beans.
    	 */
    	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 (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
    			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
    				getApplicationEventMulticaster().multicastEvent(earlyEvent);
    			}
    		}
    	}
    

    没什么复杂的逻辑

    finishBeanFactoryInitialization

    完成剩下的 (不是 lazy-init) bean 初始化

    1. 获取所有的beanDefinitionNames,然后遍历

    2. 先合并其父类的相关公共属性,返回合并的RootBeanDefinition

    3. 如果不是抽象类,而且是非懒加载的单例则开始创建Bean

    4. 首先判断是不是FactoryBean,如果是FactoryBean,使用 &+beanName ,去获取 FactoryBean

    5. 如果不是FactoryBean,则直接调用getBean(beanName);方法创建或者获取对应的Bean

    SmartInitializingSingletonSpring4.1版本之后的一个新扩展点。在创建完所有的非懒加载单例Bean之后,调用SmartInitializingSingleton接口,完成回调。

    我们例子中的 MyService 最终会调用 getBean 来完成初始化

    1297993-20200506143616640-268852002.png

    getBean 方法会在下一篇讲到 .

    finishRefresh

    	/**
    	 * Finish the refresh of this context, invoking the LifecycleProcessor's
    	 * onRefresh() method and publishing the
         * 
         *  完成 context 的 refresh 方法, 调用 LifecycleProcessor 的  onRefresh() 方法,并发布事件  
         * 
    	 * {@link org.springframework.context.event.ContextRefreshedEvent}.
    	 */
    	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);
        }
    

    参考资料

  • 相关阅读:
    22天学习java基础笔记之day08
    22天学习java基础笔记之day07
    22天学习java基础笔记之day06
    22天学习java基础笔记之day05
    架构师_设计模式_行为型_迭代器
    架构师_设计模式_行为型_命令模式
    架构师_设计模式_行为型_责任链模式
    架构师_设计模式_行为型_模板方法
    架构师_设计模式_结构型_装饰器模式
    架构师_设计模式_结构型_桥接模式
  • 原文地址:https://www.cnblogs.com/Benjious/p/15121095.html
Copyright © 2011-2022 走看看