Inside-springframework-XmlWebApplicationContext
/*****************段落1********************/
☆ 起势
★ public class ContextLoaderListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent event) {
this.contextLoader = createContextLoader();
this.contextLoader.initWebApplicationContext(event.getServletContext()); (1)
}
}
★ public class ContextLoader {
public WebApplicationContext initWebApplicationContext(ServletContext servletContext)
throws IllegalStateException, BeansException {
this.context = createWebApplicationContext(servletContext, parent);(2)
//将生成的ApplicationContext对象存入servletContext
servletContext.setAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
this.context);
}
protected WebApplicationContext createWebApplicationContext(
ServletContext servletContext, ApplicationContext parent) throws BeansException {
//通过属性文件动态加载ApplicationContext类
// contextClass= XmlWebApplicationContext
Class contextClass = determineContextClass(servletContext);
//值得学习的地方:Class. isAssignableFrom
(Class<?> cls)
// 判定此 Class
对象所表示的类或接口与指定的 Class
参数所表示的类或接
//口是否相同,或是否是其超类或超接口。
if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
throw new ApplicationContextException("Custom context class [" +
contextClass.getName() +"] is not of type ConfigurableWebApplicationContext");
}
ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext)
BeanUtils.instantiateClass(contextClass); (3)
wac.setServletContext(servletContext);
// configLocation =/WEB-INF/applicationContext-dudu.xml
String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
wac.setConfigLocations(StringUtils.tokenizeToStringArray(configLocation,
ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
//简单中隐藏复杂
wac.refresh();(4)
return wac;
}
}
(3注)
return instantiateClass(clazz.getDeclaredConstructor((Class[]) null), null);
//值得学习的地方
★ public abstract class BeanUtils {
public static Object instantiateClass(Constructor ctor, Object[] args) throws
BeanInstantiationException {
if (!Modifier.isPublic(ctor.getModifiers()) ||
!Modifier.isPublic(ctor.getDeclaringClass().getModifiers())) {
ctor.setAccessible(true);
}
return ctor.newInstance(args);
}
}
/*****************段落2********************/
☆ 起舞(处理beanDefinition和bean)
★ public abstract class AbstractRefreshableWebApplicationContext extends
AbstractRefreshableApplicationContext implements ConfigurableWebApplicationContext,
ThemeSource {
//模版模式 (4注)
public void refresh() throws BeansException {
super.refresh(); (5)
}
protected final void refreshBeanFactory() throws BeansException {(6注)
DefaultListableBeanFactory beanFactory = createBeanFactory();
loadBeanDefinitions(beanFactory);
//ApplicationContext包装BeanFactory
this.beanFactory = beanFactory;
}
}
(5注)
★ public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext, DisposableBean {
//真正的重头戏都在这里面了
public void refresh() throws BeansException, IllegalStateException {
//调用的是子类AbstractRefreshableWebApplicationContext中的同名方法
//建立DefaultListableBeanFactory对象
//从配置文件中取得bean信息,转变未BeanDefinition对象,保存在beanFactory
//的beanDefinition Names和beanDefinitionMap中
//具体过程参加“Inside-springframework-bean-definition”
refreshBeanFactory();(6)
//查找类型为org.springframework.beans.factory.
//config.BeanPostProcessor的bean,并创建之。
(7:参见Inside-springframework-Loader-registerBeanPostProcessors)
//将类型为BeanPostProcessor的bean实例化并保存在beanFactory的beanPocessors
//该类型的bean是Spring中的AopProxyFactory类型
registerBeanPostProcessors();
// 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 singletons this late to allow them to access the message source.
beanFactory.preInstantiateSingletons();
// Last step: publish corresponding event.
publishEvent(new ContextRefreshedEvent(this));
}