关于spring IOC加载过程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012262450/article/details/79914439

1、基本流程。

tomcat起来的时候加载ServletContextListener实现类,spring默认ContextLoaderListener实现了该类。




读取ContextLoader.properties文件获取XmlWebApplicationContext对象来解析xml文件、实例化对象等。



2、prepareBeanFactory方法说明

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		//设置classLoader,默认设置的是tomcat webappclassLoader
		beanFactory.setBeanClassLoader(getClassLoader()); 

		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		//配置BeanFactory回调接口,BeanPostProcessor应用于bean创建工程中
		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.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		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()));
		}
		/*
			缓存Object对象,一个beanName -> 实例
			具体见DefaultSingletonBeanRegistry类中的registerSingleton、addSingleton方法。
		*/
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());//StandardServletEnvironment
		}
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());//System.getProperties();
		}
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());//System.getenv()
		}
	}


3、postProcessBeanFactory方法说明

3.1 BeanPostProcessor接口说明

允许自定义修改新bean实例的工厂挂钩,如:在检查接口时进行标记以及代理包装

ApplicationContexts可以在其bean定义中自动检测BeanPostProcessor bean,并将它们应用于随后创建的任何bean。

主要方法为:postProcessBeforeInitialization(前置方法),postProcessAfterInitialization(后置方法)。

	@Override
	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		//设置BeanPostProcessor
		beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
		//忽略对应的接口
		beanFactory.ignoreDependencyInterface(ServletContextAware.class);
		beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
		//注册对应的web应用范围
		WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
		//见下面方法
		WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
	}
	
	public static void registerEnvironmentBeans(
			ConfigurableListableBeanFactory bf, ServletContext servletContext, ServletConfig servletConfig) {
			//缓存servletContext对象
		if (servletContext != null && !bf.containsBean(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME)) {
			bf.registerSingleton(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME, servletContext);
		}
			//缓存servletConfig对象
		if (servletConfig != null && !bf.containsBean(ConfigurableWebApplicationContext.SERVLET_CONFIG_BEAN_NAME)) {
			bf.registerSingleton(ConfigurableWebApplicationContext.SERVLET_CONFIG_BEAN_NAME, servletConfig);
		}
			//
		if (!bf.containsBean(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME)) {
			Map<String, String> parameterMap = new HashMap<String, String>();
			if (servletContext != null) {
				//CONTEXT_PARAMETERS_BEAN_NAME=contextParameters  读取web.xml中的context-param配置
				Enumeration<?> paramNameEnum = servletContext.getInitParameterNames();
				while (paramNameEnum.hasMoreElements()) {
					String paramName = (String) paramNameEnum.nextElement();
					parameterMap.put(paramName, servletContext.getInitParameter(paramName));
				}
			}
			if (servletConfig != null) {
				Enumeration<?> paramNameEnum = servletConfig.getInitParameterNames();
				while (paramNameEnum.hasMoreElements()) {
					String paramName = (String) paramNameEnum.nextElement();
					parameterMap.put(paramName, servletConfig.getInitParameter(paramName));
				}
			}
			//缓存contextParameters map对象
			bf.registerSingleton(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME,
					Collections.unmodifiableMap(parameterMap));
		}

		if (!bf.containsBean(WebApplicationContext.CONTEXT_ATTRIBUTES_BEAN_NAME)) {
			Map<String, Object> attributeMap = new HashMap<String, Object>();
			if (servletContext != null) {
				//CONTEXT_ATTRIBUTES_BEAN_NAME = contextAttributes 从servletContext获取属性以及属性值。
				Enumeration<?> attrNameEnum = servletContext.getAttributeNames();
				while (attrNameEnum.hasMoreElements()) {
					String attrName = (String) attrNameEnum.nextElement();
					attributeMap.put(attrName, servletContext.getAttribute(attrName));
				}
			}
			//将servlet属性值封装到一个map中,包括是在从tomcat缓存的一些属性值
			bf.registerSingleton(WebApplicationContext.CONTEXT_ATTRIBUTES_BEAN_NAME,
					Collections.unmodifiableMap(attributeMap));
		}
	}



4、invokeBeanFactoryPostProcessors方法说明

4.1 BeanFactoryPostProcessor接口说明

允许自定义修改应用程序上下文的bean定义,调整上下文的基础bean工厂的bean属性值。
应用程序上下文可以在其bean定义中自动检测BeanFactoryPostProcessor bean,并在创建任何其他bean之前应用它们。
对于定制配置文件非常有用,这些文件针对系统管理员,覆盖应用程序上下文中配置的bean属性

BeanFactoryPostProcessor可能与bean定义交互并修改,但永远不会bean实例。 这样做可能会导致bean过早实例化,违反容器并导致意想不到的副作用。如果需要bean实例交互,请考虑实现 BeanPostProcessor。

4.2 BeanDefinitionRegistryPostProcessor接口说明

扩展到标准的 BeanFactoryPostProcessor 接口,允许在正常的BeanFactoryPostProcessor检测开始之前注册更多的bean定义。特别是,BeanDefinitionRegistryPostProcessor可以注册更多的bean定义,然后定义BeanFactoryPostProcessor实例。


/*
整体思路:

	1、先遍历容器自带的BeanDefinitionRegistryPostProcessor接口,且执行postProcessBeanDefinitionRegistry方法,
	没有实现BeanDefinitionRegistryPostProcessor接口,那么添加到regularPostProcessors集合中
	
	2、从容器中找到BeanDefinitionRegistryPostProcessor接口实现类且也实现了PriorityOrdered接口,
	执行postProcessBeanDefinitionRegistry方法,获取到priorityOrderedPostProcessors数据存放到registryPostProcessors集合中
	
	3、同第二步类似,这次实现了是Ordered接口,执行postProcessBeanDefinitionRegistry方法。
	获取到orderedPostProcessors数据存放到registryPostProcessors集合中

	4、同第二步、第三类似,只是找到既没有实现Ordered接口也没有实现PriorityOrdered接口。
	
	5、执行所有的BeanFactoryPostProcessor接口。
	
	6、获取所有BeanFactoryPostProcessor接口实现类,整理对应的接口,如:PriorityOrdered、Ordered
	
	7、一次执行对应的接口
	
	按照优先级划分:
	BeanDefinitionRegistryPostProcessor接口实现类:--> 且实现PriorityOrdered接口类先执行,其次是Ordered,最后就是只实现BeanDefinitionRegistryPostProcessor接口的类
	
	BeanFactoryPostProcessor接口实现类:--> 且实现PriorityOrdered接口类先执行,其次是Ordered,最后就是只实现BeanFactoryPostProcessor接口的类
	
*/
public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
		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>();
			//第一次容器加载时,beanFactoryPostProcessors为空。
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryPostProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
					registryPostProcessors.add(registryPostProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}
			// 根据BeanDefinitionRegistryPostProcessor类型,从beanFactory中获取所有的beanName
			// 优先执行PriorityOrdered接口
			
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
			for (String ppName : postProcessorNames) {
					//遍历查找获取的BeanDefinitionRegistryPostProcessor bean是否实现了PriorityOrdered接口
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					
					priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
			registryPostProcessors.addAll(priorityOrderedPostProcessors);
			invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);

		
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
			for (String ppName : postProcessorNames) {
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			//排序
			sortPostProcessors(beanFactory, orderedPostProcessors);
			registryPostProcessors.addAll(orderedPostProcessors);
			//执行postProcessBeanDefinitionRegistry方法
			invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);

			// 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)) {
						BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
						registryPostProcessors.add(pp);
						processedBeans.add(ppName);
						pp.postProcessBeanDefinitionRegistry(registry);
						reiterate = true;
					}
				}
			}

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			invokeBeanFactoryPostProcessors(registryPostProcessors, 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<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 (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(beanFactory, priorityOrderedPostProcessors);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

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

		// Finally, invoke all other BeanFactoryPostProcessors.
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
		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();
	}

下次继续分析。

猜你喜欢

转载自blog.csdn.net/u012262450/article/details/79914439