`

Spring Beanfactory initialize 源码浅析

阅读更多
 We can create Beanfactory by ClassPathXmlApplicationContext. The following code will create new beanfactory instance.
Beanfactory beanfactory = new ClassPathXmlApplicationContext("applicationContext.xml") 

 

	/**
	 * Create a new ClassPathXmlApplicationContext, loading the definitions
	 * from the given XML files and automatically refreshing the context.
	 * @param configLocations array of resource locations
	 * @throws BeansException if context creation failed
	 */
	public ClassPathXmlApplicationContext(String... configLocations) throws BeansException {
		this(configLocations, true, null);
	}

 

It first initialize the parent class, then set the config locations for this application context. If not set, it will use default config file named "applicationConext.xml". In the last, refresh the beanfactory.
	public ClaassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
			throws BeansException {

		super(parent);
		setConfigLocations(configLocations);
		if (refresh) {
			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.
			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.
				postProcessBeanFactory(beanFactory);

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

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

				// Initialize message source for this context.
				initMessageSource();

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

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

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

				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

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

				// Propagate exception to caller.
				throw ex;
			}
		}
	}
 There are several setps in the refresh() method. It includes the most important and complicate logic. The first step is to prepare for refresh.
	/**
	 * Prepare this context for refreshing, setting its startup date and
	 * active flag as well as performing any initialization of property sources.
	 */
	protected void prepareRefresh() {
		this.startupDate = System.currentTimeMillis();

		synchronized (this.activeMonitor) {
			this.active = true;
		}

		if (logger.isInfoEnabled()) {
			logger.info("Refreshing " + this);
		}

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

		// Validate that all properties marked as required are resolvable
		// see ConfigurablePropertyResolver#setRequiredProperties
		this.environment.validateRequiredProperties();
	}
 
The following step is to get new beanfacory. It includes create beanfacory and load bean definitions.
	/**
	 * Tell the subclass to refresh the internal bean factory.
	 * @return the fresh BeanFactory instance
	 * @see #refreshBeanFactory()
	 * @see #getBeanFactory()
	 */
	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		refreshBeanFactory();
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
		}
		return beanFactory;
	}
 
	/**
	 * This implementation performs an actual refresh of this context's underlying
	 * bean factory, shutting down the previous bean factory (if any) and
	 * initializing a fresh bean factory for the next phase of the context's lifecycle.
	 */
	@Override
	protected final void refreshBeanFactory() throws BeansException {
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());
			customizeBeanFactory(beanFactory);
			loadBeanDefinitions(beanFactory);
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}
 prepareBeanFactory:  Include setBeanClassLoader, setBeanExpressionResolver, addPropertyEditorRegistrar, addBeanPostProcessor, ignoreDependencyInterface, registerResolvableDependency, etc.
	/**
	 * Configure the factory's standard context characteristics,
	 * such as the context's ClassLoader and post-processors.
	 * @param beanFactory the BeanFactory to configure
	 */
	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// Tell the internal bean factory to use the context's class loader etc.
		beanFactory.setBeanClassLoader(getClassLoader());
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));

		// Configure the bean factory with context callbacks.
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);

		// BeanFactory interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, 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.containsBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}

		if (!beanFactory.containsBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}

		if (!beanFactory.containsBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
	}
 
postProcessBeanFactory : allow subclass to override it and do some post process.
invokeBeanFactoryPostProcessors: it will Instantiate and invoke all registered BeanFactoryPostProcessor beans.
	/**
	 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
	 * respecting explicit order if given.
	 * <p>Must be called before singleton instantiation.
	 */
	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		Set<String> processedBeans = new HashSet<String>();
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
			List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
					new LinkedList<BeanDefinitionRegistryPostProcessor>();
			for (BeanFactoryPostProcessor postProcessor : getBeanFactoryPostProcessors()) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryPostProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
					registryPostProcessors.add(registryPostProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}
			Map<String, BeanDefinitionRegistryPostProcessor> beanMap =
					beanFactory.getBeansOfType(BeanDefinitionRegistryPostProcessor.class, true, false);
			List<BeanDefinitionRegistryPostProcessor> registryPostProcessorBeans =
					new ArrayList<BeanDefinitionRegistryPostProcessor>(beanMap.values());
			OrderComparator.sort(registryPostProcessorBeans);
			for (BeanDefinitionRegistryPostProcessor postProcessor : registryPostProcessorBeans) {
				postProcessor.postProcessBeanDefinitionRegistry(registry);
			}
			invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(registryPostProcessorBeans, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
			processedBeans.addAll(beanMap.keySet());
		}
		else {
			// Invoke factory processors registered with the context instance.
			invokeBeanFactoryPostProcessors(getBeanFactoryPostProcessors(), 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<BeanFactoryPostProcessor>();
		List<String> orderedPostProcessorNames = new ArrayList<String>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
		for (String ppName : postProcessorNames) {
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			}
			else if (isTypeMatch(ppName, PriorityOrdered.class)) {
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
		OrderComparator.sort(priorityOrderedPostProcessors);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		OrderComparator.sort(orderedPostProcessors);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// Finally, invoke all other BeanFactoryPostProcessors.
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
	}
    
 // Register bean processors that intercept bean creation.
    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.
    registerListeners();
 
finishBeanFactoryInitialization : will instantiate all remaining bean which is (non-lazy-init) singletons.
	/**
	 * Finish the initialization of this context's bean factory,
	 * initializing all remaining singleton beans.
	 */
	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		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));
		}

		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		// Allow for caching all bean definition metadata, not expecting further changes.
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		beanFactory.preInstantiateSingletons();
	}
 
finishRefresh : will invoking the LifecycleProcessor's onRefresh() method and publishing the org.springframework.context.event.ContextRefreshedEvent.
	/**
	 * Finish the refresh of this context, invoking the LifecycleProcessor's
	 * onRefresh() method and publishing the
	 * {@link org.springframework.context.event.ContextRefreshedEvent}.
	 */
	protected void finishRefresh() {
		// Initialize lifecycle processor for this context.
		initLifecycleProcessor();

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

		// Publish the final event.
		publishEvent(new ContextRefreshedEvent(this));
	}
 
分享到:
评论

相关推荐

    Spring的BeanFactory的接口源码中文解释

    Spring的BeanFactory的接口的中文解释

    二、Spring源码分析——BeanFactory

    《Spring源码分析——BeanFactory》 在Java的IoC(Inversion of Control)和DI(Dependency Injection)领域,Spring框架扮演着至关重要的角色。BeanFactory是Spring的核心组件之一,它是容器的基石,负责管理应用...

    简单模拟Spring的beanFactory

    本文将通过模拟Spring的`BeanFactory`来深入理解其工作原理,帮助开发者更好地掌握Spring的核心概念。 `BeanFactory`是Spring框架中最基础的bean管理容器,它是所有更高级别的容器(如`ApplicationContext`)的基类...

    Spring源码深度解析第二版

    Spring源码深度解析第二版 Spring是一款广泛应用于Java企业级应用程序的开源框架,旨在简化Java应用程序的开发和部署。Spring框架的核心主要包括了IoC容器、AOP、MVC框架等模块。 第1章 Spring整体架构和环境搭建 ...

    spring1.2.6源码

    源码中,你可以看到`BeanFactory`接口及其实现类`ApplicationContext`,它们负责创建、配置和管理应用中的bean。理解`BeanDefinition`如何存储bean的元数据,以及`InstantiationAwareBeanPostProcessor`如何在bean...

    spring-core源码

    《深入剖析Spring Core源码》 Spring Core是Spring框架的核心部分,它提供了依赖注入(Dependency Injection,DI)和控制反转(Inversion of Control,IoC)等关键特性,是整个Spring框架的基础。当我们谈论Spring ...

    spring 源码中文注释

    在源码中,`BeanFactory`和`ApplicationContext`接口是IoC容器的主要代表,前者是基础版本,后者提供了更多的企业级特性,如事件发布、国际化支持等。 接着,AOP是Spring的另一大特色。AOP允许开发者定义“切面”,...

    Spring2(源码)

    - Spring通过Bean工厂(BeanFactory)和应用上下文(ApplicationContext)管理对象,它们负责创建、配置和管理Bean。 - Bean定义包含Bean的属性、依赖关系等信息,Spring通过反射机制读取这些信息并执行相应的注入...

    spring源码注释中文

    - **Spring 容器**:探究 BeanFactory 和 ApplicationContext 的区别,以及如何通过它们管理对象的生命周期。 - **数据访问**:了解 Spring 如何整合各种 ORM 和 OXM 框架,以及如何实现数据访问层的事务管理。 ...

    spring-context源码

    《深入剖析Spring-Context源码》 Spring框架是Java企业级应用开发的基石,而`spring-context`模块则是Spring框架的核心部分,它提供了上下文(ApplicationContext)接口,为bean的创建、配置、管理以及与其他服务的...

    spring源码中英文注释

    这个压缩包文件中的"spring源码 中英文注释"为开发者提供了一个深入理解Spring框架内部工作原理的机会。通过阅读源码和注释,我们可以更清晰地了解Spring如何管理依赖注入、AOP(面向切面编程)、事务管理、上下文...

    Spring5全部源码

    阅读Spring源码有助于理解其实现原理,你可以从核心模块开始,例如BeanFactory和ApplicationContext的实现,然后深入到AOP、DI和MVC框架。同时,了解Spring的模块化设计和设计模式的运用也是很重要的。 通过深入...

    spring源码合集spring源码合集

    《Spring源码合集:揭示Java后端开发的基石》 Spring框架作为Java后端开发的核心,其源码的研究对于提升开发者对系统架构理解和优化能力至关重要。本合集深入剖析了Spring的诸多关键特性,包括依赖注入、配置类解析...

    Spring源码分析.pdf

    Spring 源码分析 Spring 框架是 Java 语言中最流行的开源框架之一,它提供了一个强大且灵活的基础设施来构建企业级应用程序。在 Spring 框架中,IOC 容器扮演着核心角色,本文将深入分析 Spring 源码,了解 IOC ...

    spring-beans源码

    《深入剖析Spring Beans源码》 Spring框架是Java开发中不可或缺的部分,其核心组件之一就是`spring-beans`模块。这个模块主要负责Spring容器的创建、管理Bean的生命周期以及依赖注入(Dependency Injection,简称DI...

    spring源码-2022-08-14spring源码spring源码spring源码

    在2022年8月14日更新的Spring源码中,我们可以深入理解其设计理念和实现机制。 Spring框架的主要组成部分包括: 1. **核心容器**:这是Spring的基础,主要包括BeanFactory和ApplicationContext。BeanFactory负责...

    spring 框架源码 版本:5.2.9.RELEASE

    在源码中,你可以看到IoC容器是如何通过BeanFactory和ApplicationContext来管理对象生命周期的,以及如何通过@Autowired注解实现自动装配。 其次,Spring的AOP(面向切面编程)允许开发者定义横切关注点,如日志、...

    spring-framework-1.0-m1.zip源码

    2. BeanFactory:作为ApplicationContext的底层实现,BeanFactory是Spring的核心容器,负责Bean的实例化、配置和管理。它提供了基本的DI功能,但功能相对较少,适合小型项目。 3. AOP(面向切面编程):Spring 1.0...

    构建为eclipse项目的spring源码

    例如,研究`org.springframework.beans.factory.BeanFactory`接口及其实现,了解依赖注入的过程。 - **设置断点**:在关键代码处设置断点,通过Debug模式运行,观察类实例化、依赖注入、方法调用等流程,深入理解...

    spring源码分析(1-10)

    BeanFactory是基础接口,提供了创建、查找和管理bean的能力。AbstractBeanFactory和DefaultListableBeanFactory是实际实现,它们加载bean定义并创建bean实例。Bean定义通常来自XML文件,但也可以是其他格式如Java...

Global site tag (gtag.js) - Google Analytics