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 parameterMap = new HashMap();
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 attributeMap = new HashMap();
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 beanFactoryPostProcessors) {
Set processedBeans = new HashSet();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List regularPostProcessors = new LinkedList();
List registryPostProcessors =
new LinkedList();
//第一次容器加载时,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 priorityOrderedPostProcessors = new ArrayList();
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 orderedPostProcessors = new ArrayList();
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 priorityOrderedPostProcessors = new ArrayList();
List orderedPostProcessorNames = new ArrayList();
List 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(beanFactory, priorityOrderedPostProcessors);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List orderedPostProcessors = new ArrayList();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(beanFactory, orderedPostProcessors);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List nonOrderedPostProcessors = new ArrayList();
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();
}
下次继续分析。