一般在web应用配置Spring上下文如下,那么ContextLoaderListener到底做了什么呢,我们来看一下
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/ApplicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
ruid/*</url-pattern>
</web-app>
//上下文加载监听器
public class ContextLoaderListener extends ContextLoader
implements ServletContextListener
{
public ContextLoaderListener(WebApplicationContext context)
{
super(context);
}
public void contextInitialized(ServletContextEvent event)
{
//初始化WebApplicationContext
initWebApplicationContext(event.getServletContext());
}
public void contextDestroyed(ServletContextEvent event)
{
closeWebApplicationContext(event.getServletContext());
ContextCleanupListener.cleanupAttributes(event.getServletContext());
}
}
//上下文加载器
public class ContextLoader
{
public ContextLoader(WebApplicationContext context)
{
this.context = context;
}
public WebApplicationContext initWebApplicationContext(ServletContext servletContext)
{
Log logger;
long startTime;
//如果servletContext的WebApplicationContext.root属性存在,则抛出根应用上下文已经初始化异常
if(servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null)
throw new IllegalStateException("Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!");
logger = LogFactory.getLog(org/springframework/web/context/ContextLoader);
servletContext.log("Initializing Spring root WebApplicationContext");
if(logger.isInfoEnabled())
logger.info("Root WebApplicationContext: initialization started");
startTime = System.currentTimeMillis();
if(context == null)
context = createWebApplicationContext(servletContext);
if(context instanceof ConfigurableWebApplicationContext)
{
ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext)context;
if(!cwac.isActive())
{
if(cwac.getParent() == null)
{
//加载应用上下文
ApplicationContext parent = loadParentContext(servletContext);
//设置web上下文的父上下文
cwac.setParent(parent);
}
//设置并刷新WebApplicationContext
configureAndRefreshWebApplicationContext(cwac, servletContext);
}
}
//设置WebApplicationContext的root属性
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, context);
ClassLoader ccl = Thread.currentThread().getContextClassLoader();
if(ccl == org/springframework/web/context/ContextLoader.getClassLoader())
currentContext = context;
else
if(ccl != null)
//设置当前线程的上下文
currentContextPerThread.put(ccl, context);
if(logger.isDebugEnabled())
logger.debug((new StringBuilder()).append("Published root WebApplicationContext as ServletContext attribute with name [").append(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE).append("]").toString());
if(logger.isInfoEnabled())
{
long elapsedTime = System.currentTimeMillis() - startTime;
logger.info((new StringBuilder()).append("Root WebApplicationContext: initialization completed in ").append(elapsedTime).append(" ms").toString());
}
return context;
RuntimeException ex;
ex;
logger.error("Context initialization failed", ex);
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
throw ex;
Error err;
err;
logger.error("Context initialization failed", err);
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
throw err;
}
//创建WebApplicationContext
protected WebApplicationContext createWebApplicationContext(ServletContext sc)
{
Class contextClass = determineContextClass(sc);
if(!org/springframework/web/context/ConfigurableWebApplicationContext.isAssignableFrom(contextClass))
throw new ApplicationContextException((new StringBuilder()).append("Custom context class [").append(contextClass.getName()).append("] is not of type [").append(org/springframework/web/context/ConfigurableWebApplicationContext.getName()).append("]").toString());
else
return (ConfigurableWebApplicationContext)BeanUtils.instantiateClass(contextClass);
}
//获取ContextClass
protected Class determineContextClass(ServletContext servletContext)
{
String contextClassName;
contextClassName = servletContext.getInitParameter("contextClass");
if(contextClassName == null)
break MISSING_BLOCK_LABEL_55;
return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader());
throw new ApplicationContextException((new StringBuilder()).append("Failed to load custom context class [").append(contextClassName).append("]").toString(), ex);
contextClassName = defaultStrategies.getProperty(org/springframework/web/context/WebApplicationContext.getName());
return ClassUtils.forName(contextClassName, org/springframework/web/context/ContextLoader.getClassLoader());
throw new ApplicationContextException((new StringBuilder()).append("Failed to load default context class [").append(contextClassName).append("]").toString(), ex);
}
//加载应用上下文
protected ApplicationContext loadParentContext(ServletContext servletContext)
{
ApplicationContext parentContext = null;
String locatorFactorySelector = servletContext.getInitParameter("locatorFactorySelector");
String parentContextKey = servletContext.getInitParameter("parentContextKey");
if(parentContextKey != null)
{
BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector);
Log logger = LogFactory.getLog(org/springframework/web/context/ContextLoader);
if(logger.isDebugEnabled())
logger.debug((new StringBuilder()).append("Getting parent context definition: using parent context key of '").append(parentContextKey).append("' with BeanFactoryLocator").toString());
parentContextRef = locator.useBeanFactory(parentContextKey);
//获取父应用上下文
parentContext = (ApplicationContext)parentContextRef.getFactory();
}
return parentContext;
}
//设置并刷新WebApplicationContext
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc)
{
if(ObjectUtils.identityToString(wac).equals(wac.getId()))
{
String idParam = sc.getInitParameter("contextId");
if(idParam != null)
wac.setId(idParam);
else
wac.setId((new StringBuilder()).append(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX).append(ObjectUtils.getDisplayString(sc.getContextPath())).toString());
}
//设置web上下文的ServletContext
wac.setServletContext(sc);
//获取上下文位置
String configLocationParam = sc.getInitParameter("contextConfigLocation");
if(configLocationParam != null)
wac.setConfigLocation(configLocationParam);
ConfigurableEnvironment env = wac.getEnvironment();
if(env instanceof ConfigurableWebEnvironment)
((ConfigurableWebEnvironment)env).initPropertySources(sc, null);
customizeContext(sc, wac);
//bean容器初始化,关键
wac.refresh();
}
protected void customizeContext(ServletContext sc, ConfigurableWebApplicationContext wac)
{
List initializerClasses = determineContextInitializerClasses(sc);
if(initializerClasses.isEmpty())
return;
ArrayList initializerInstances = new ArrayList();
Class initializerClass;
for(Iterator iterator = initializerClasses.iterator(); iterator.hasNext(); initializerInstances.add(BeanUtils.instantiateClass(initializerClass)))
{
initializerClass = (Class)iterator.next();
//解决初始化类,类型问题
Class initializerContextClass = GenericTypeResolver.resolveTypeArgument(initializerClass, org/springframework/context/ApplicationContextInitializer);
if(initializerContextClass != null)
Assert.isAssignable(initializerContextClass, wac.getClass(), String.format("Could not add context initializer [%s] since its generic parameter [%s] is not assignable from the type of application context used by this context loader [%s]: ", new Object[] {
initializerClass.getName(), initializerContextClass.getName(), wac.getClass().getName()
}));
}
AnnotationAwareOrderComparator.sort(initializerInstances);
ApplicationContextInitializer initializer;
for(Iterator iterator1 = initializerInstances.iterator(); iterator1.hasNext(); initializer.initialize(wac))
initializer = (ApplicationContextInitializer)iterator1.next();
}
//获取需要上下文需要初始化的类
protected List determineContextInitializerClasses(ServletContext servletContext)
{
List classes = new ArrayList();
String globalClassNames = servletContext.getInitParameter("globalInitializerClasses");
if(globalClassNames != null)
{
String as[] = StringUtils.tokenizeToStringArray(globalClassNames, ",; \t\n");
int i = as.length;
for(int j = 0; j < i; j++)
{
String className = as[j];
classes.add(loadInitializerClass(className));
}
}
String localClassNames = servletContext.getInitParameter("contextInitializerClasses");
if(localClassNames != null)
{
String as1[] = StringUtils.tokenizeToStringArray(localClassNames, ",; \t\n");
int k = as1.length;
for(int l = 0; l < k; l++)
{
String className = as1[l];
classes.add(loadInitializerClass(className));
}
}
return classes;
}
//根据className获取需要加载的Class
private Class loadInitializerClass(String className)
{
Class clazz;
clazz = ClassUtils.forName(className, ClassUtils.getDefaultClassLoader());
Assert.isAssignable(org/springframework/context/ApplicationContextInitializer, clazz);
return clazz;
ClassNotFoundException ex;
ex;
throw new ApplicationContextException((new StringBuilder()).append("Failed to load context initializer class [").append(className).append("]").toString(), ex);
}
public static final String CONTEXT_ID_PARAM = "contextId";
public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";
public static final String CONTEXT_CLASS_PARAM = "contextClass";
public static final String CONTEXT_INITIALIZER_CLASSES_PARAM = "contextInitializerClasses";
public static final String GLOBAL_INITIALIZER_CLASSES_PARAM = "globalInitializerClasses";
public static final String LOCATOR_FACTORY_SELECTOR_PARAM = "locatorFactorySelector";
public static final String LOCATOR_FACTORY_KEY_PARAM = "parentContextKey";
private static final String INIT_PARAM_DELIMITERS = ",; \t\n";
private static final String DEFAULT_STRATEGIES_PATH = "ContextLoader.properties";
private static final Properties defaultStrategies;
private static final Map currentContextPerThread = new ConcurrentHashMap(1);
private static volatile WebApplicationContext currentContext;
private WebApplicationContext context;//web应用上下恩
private BeanFactoryReference parentContextRef;//父上下文的bean工厂引用
static
{
try
{ //创建上下文配置文件资源
ClassPathResource resource = new ClassPathResource("ContextLoader.properties", org/springframework/web/context/ContextLoader);
//加载上下文配置文件
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
}
catch(IOException ex)
{
throw new IllegalStateException((new StringBuilder()).append("Could not load 'ContextLoader.properties': ").append(ex.getMessage()).toString());
}
}
}
//抽象应用上下文
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext, DisposableBean
{
public AbstractApplicationContext()
{
logger = LogFactory.getLog(getClass());
id = ObjectUtils.identityToString(this);
displayName = ObjectUtils.identityToString(this);
beanFactoryPostProcessors = new ArrayList();
active = false;
closed = false;
activeMonitor = new Object();
startupShutdownMonitor = new Object();
applicationListeners = new LinkedHashSet();
resourcePatternResolver = getResourcePatternResolver();
}
public AbstractApplicationContext(ApplicationContext parent)
{
this();
setParent(parent);
}
//设置父应用上下文
public void setParent(ApplicationContext parent)
{
this.parent = parent;
if(parent != null)
{
Environment parentEnvironment = parent.getEnvironment();
if(parentEnvironment instanceof ConfigurableEnvironment)
getEnvironment().merge((ConfigurableEnvironment)parentEnvironment);
}
}
public void refresh()
throws BeansException, IllegalStateException
{
synchronized(startupShutdownMonitor)
{
//准备刷新
prepareRefresh();
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//bean容器准备工作
prepareBeanFactory(beanFactory);
try
{
//bean后置处理器配置
postProcessBeanFactory(beanFactory);
//bean容器解析构造bean,关键
invokeBeanFactoryPostProcessors(beanFactory);
registerBeanPostProcessors(beanFactory);
//初始化消息源
initMessageSource();
initApplicationEventMulticaster();
onRefresh();
//注册应用监听器
registerListeners();
//初始化bean容器
finishBeanFactoryInitialization(beanFactory);
finishRefresh();
}
catch(BeansException ex)
{
destroyBeans();
cancelRefresh(ex);
throw ex;
}
}
}
//准备刷新
protected void prepareRefresh()
{
startupDate = System.currentTimeMillis();
synchronized(activeMonitor)
{
active = true;
}
if(logger.isInfoEnabled())
logger.info((new StringBuilder()).append("Refreshing ").append(this).toString());
//初始化属性员
initPropertySources();
//校验必须的属性
getEnvironment().validateRequiredProperties();
}
protected void initPropertySources()
{
}
//获取ConfigurableListableBeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory()
{
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if(logger.isDebugEnabled())
logger.debug((new StringBuilder()).append("Bean factory for ").append(getDisplayName()).append(": ").append(beanFactory).toString());
return beanFactory;
}
//获取内部父bean容器
protected BeanFactory getInternalParentBeanFactory()
{
return ((BeanFactory) ((getParent() instanceof ConfigurableApplicationContext) ? ((ConfigurableApplicationContext)getParent()).getBeanFactory() : getParent()));
}
//bean容器准备工作
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory)
{
//bean容器类加载器
beanFactory.setBeanClassLoader(getClassLoader());
//bean容器Expression解决器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
//添加bean后置处理器
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(org/springframework/context/ResourceLoaderAware);
beanFactory.ignoreDependencyInterface(org/springframework/context/ApplicationEventPublisherAware);
beanFactory.ignoreDependencyInterface(org/springframework/context/MessageSourceAware);
beanFactory.ignoreDependencyInterface(org/springframework/context/ApplicationContextAware);
beanFactory.ignoreDependencyInterface(org/springframework/context/EnvironmentAware);
beanFactory.registerResolvableDependency(org/springframework/beans/factory/BeanFactory, beanFactory);
beanFactory.registerResolvableDependency(org/springframework/core/io/ResourceLoader, this);
beanFactory.registerResolvableDependency(org/springframework/context/ApplicationEventPublisher, this);
beanFactory.registerResolvableDependency(org/springframework/context/ApplicationContext, this);
if(beanFactory.containsBean("loadTimeWeaver"))
{
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
if(!beanFactory.containsLocalBean("environment"))
beanFactory.registerSingleton("environment", getEnvironment());
if(!beanFactory.containsLocalBean("systemProperties"))
beanFactory.registerSingleton("systemProperties", getEnvironment().getSystemProperties());
if(!beanFactory.containsLocalBean("systemEnvironment"))
beanFactory.registerSingleton("systemEnvironment", getEnvironment().getSystemEnvironment());
}
//bean后置处理器配置
protected void postProcessBeanFactory(ConfigurableListableBeanFactory configurablelistablebeanfactory)
{
}
//bean容器解析构造bean
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory)
{
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}
//初始化消息源
protected void initMessageSource()
{
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if(beanFactory.containsLocalBean("messageSource"))
{
messageSource = (MessageSource)beanFactory.getBean("messageSource", org/springframework/context/MessageSource);
if(parent != null && (messageSource instanceof HierarchicalMessageSource))
{
HierarchicalMessageSource hms = (HierarchicalMessageSource)messageSource;
if(hms.getParentMessageSource() == null)
hms.setParentMessageSource(getInternalParentMessageSource());
}
if(logger.isDebugEnabled())
logger.debug((new StringBuilder()).append("Using MessageSource [").append(messageSource).append("]").toString());
} else
{
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
messageSource = dms;
beanFactory.registerSingleton("messageSource", messageSource);
if(logger.isDebugEnabled())
logger.debug((new StringBuilder()).append("Unable to locate MessageSource with name 'messageSource': using default [").append(messageSource).append("]").toString());
}
}
protected void onRefresh()
throws BeansException
{
}
//注册应用监听器
protected void registerListeners()
{
ApplicationListener listener;
for(Iterator iterator = getApplicationListeners().iterator(); iterator.hasNext(); getApplicationEventMulticaster().addApplicationListener(listener))
listener = (ApplicationListener)iterator.next();
String listenerBeanNames[] = getBeanNamesForType(org/springframework/context/ApplicationListener, true, false);
String as[] = listenerBeanNames;
int i = as.length;
for(int j = 0; j < i; j++)
{
String lisName = as[j];
getApplicationEventMulticaster().addApplicationListenerBean(lisName);
}
}
//初始化bean容器
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory)
{
if(beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", org/springframework/core/convert/ConversionService))
beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", org/springframework/core/convert/ConversionService));
String weaverAwareNames[] = beanFactory.getBeanNamesForType(org/springframework/context/weaving/LoadTimeWeaverAware, false, false);
String as[] = weaverAwareNames;
int i = as.length;
for(int j = 0; j < i; j++)
{
String weaverAwareName = as[j];
getBean(weaverAwareName);
}
beanFactory.setTempClassLoader(null);
beanFactory.freezeConfiguration();
beanFactory.preInstantiateSingletons();
}
public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";
public static final String LIFECYCLE_PROCESSOR_BEAN_NAME = "lifecycleProcessor";
public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
protected final Log logger;
private String id;
private String displayName;
private ApplicationContext parent;
private final List beanFactoryPostProcessors;//bean后置处理器
private long startupDate;
private boolean active;
private boolean closed;
private final Object activeMonitor;//激活同步监控锁
private final Object startupShutdownMonitor;//启动关闭同步监控锁
private Thread shutdownHook;
private ResourcePatternResolver resourcePatternResolver;//资源解决其
private LifecycleProcessor lifecycleProcessor;
private MessageSource messageSource;//国际化消息处理
private ApplicationEventMulticaster applicationEventMulticaster;
private Set applicationListeners;
private ConfigurableEnvironment environment;
static
{
org/springframework/context/event/ContextClosedEvent.getName();
}
}
//AbstractRefreshableApplicationContext
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext
{
//刷新bean容器
protected final void refreshBeanFactory()
throws BeansException
{
if(hasBeanFactory())
{
destroyBeans();
closeBeanFactory();
}
try
{
//创建bean容器
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
//定制bean容器
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
synchronized(beanFactoryMonitor)
{
this.beanFactory = beanFactory;
}
}
}
//创建bean容器
protected DefaultListableBeanFactory createBeanFactory()
{
return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
//定制bean容器
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory)
{
if(allowBeanDefinitionOverriding != null)
beanFactory.setAllowBeanDefinitionOverriding(allowBeanDefinitionOverriding.booleanValue());
if(allowCircularReferences != null)
//是否允许环路引用
beanFactory.setAllowCircularReferences(allowCircularReferences.booleanValue());
}
//加载bean容器定义
protected abstract void loadBeanDefinitions(DefaultListableBeanFactory defaultlistablebeanfactory)
throws BeansException, IOException;
private Boolean allowBeanDefinitionOverriding;
private Boolean allowCircularReferences;
private DefaultListableBeanFactory beanFactory;
private final Object beanFactoryMonitor;
}
//默认bean容器
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable
{
private static Class javaxInjectProviderClass = null;
private static final Map serializableFactories = new ConcurrentHashMap(8);
private String serializationId;
private boolean allowBeanDefinitionOverriding;
private boolean allowEagerClassLoading;
private Comparator dependencyComparator;
private AutowireCandidateResolver autowireCandidateResolver;
private final Map resolvableDependencies;
private final Map beanDefinitionMap;//bean定义
private final Map allBeanNamesByType;
private final Map singletonBeanNamesByType;//单例bean
private final List beanDefinitionNames;//beanNames,List
private boolean configurationFrozen;
private String frozenBeanDefinitionNames[];
static
{
try
{
javaxInjectProviderClass = ClassUtils.forName("javax.inject.Provider", org/springframework/beans/factory/support/DefaultListableBeanFactory.getClassLoader());
}
}
}
//bean注册代理
class PostProcessorRegistrationDelegate
{
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();
for(Iterator iterator = beanFactoryPostProcessors.iterator(); iterator.hasNext();)
{
BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)iterator.next();
if(postProcessor instanceof BeanDefinitionRegistryPostProcessor)
{
BeanDefinitionRegistryPostProcessor registryPostProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;
registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
registryPostProcessors.add(registryPostProcessor);
} else
{
regularPostProcessors.add(postProcessor);
}
}
for(boolean reiterate = true; reiterate;)
{
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(org/springframework/beans/factory/support/BeanDefinitionRegistryPostProcessor, true, false);
String as3[] = postProcessorNames;
int k1 = as3.length;
int l1 = 0;
while(l1 < k1)
{
String ppName = as3[l1];
if(!processedBeans.contains(ppName))
{
BeanDefinitionRegistryPostProcessor pp = (BeanDefinitionRegistryPostProcessor)beanFactory.getBean(ppName, org/springframework/beans/factory/support/BeanDefinitionRegistryPostProcessor);
registryPostProcessors.add(pp);
processedBeans.add(ppName);
//注册bean,关键在这
pp.postProcessBeanDefinitionRegistry(registry);
reiterate = true;
}
l1++;
}
}
}
}
//bean配置处理器
public class ConfigurationClassPostProcessor
implements BeanDefinitionRegistryPostProcessor, PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware
{
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
{
if(factoriesPostProcessed.contains(Integer.valueOf(registryId)))
{
throw new IllegalStateException((new StringBuilder()).append("postProcessBeanFactory already called for this post-processor against ").append(registry).toString());
} else
{
//处理bean的定义
processConfigBeanDefinitions(registry);
}
}
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry)
{
Set configCandidates = new LinkedHashSet();
String as[] = registry.getBeanDefinitionNames();
int i = as.length;
for(int j = 0; j < i; j++)
{
String beanName = as[j];
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if(ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, metadataReaderFactory))
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
ConfigurationClassParser parser = new ConfigurationClassParser(metadataReaderFactory, problemReporter, environment, resourceLoader, componentScanBeanNameGenerator, registry);
//根据bean配置,解析bean
parser.parse(configCandidates);
parser.validate();
}
}
//bean配置解析
class ConfigurationClassParser
{
public ConfigurationClassParser(MetadataReaderFactory metadataReaderFactory, ProblemReporter problemReporter, Environment environment, ResourceLoader resourceLoader, BeanNameGenerator componentScanBeanNameGenerator, BeanDefinitionRegistry registry)
{
this.metadataReaderFactory = metadataReaderFactory;
this.problemReporter = problemReporter;
this.environment = environment;
this.resourceLoader = resourceLoader;
this.registry = registry;
//组件注解扫面解析器
componentScanParser = new ComponentScanAnnotationParser(resourceLoader, environment, componentScanBeanNameGenerator, registry);
conditionEvaluator = new ConditionEvaluator(registry, environment, resourceLoader);
}
//根据bean配置,解析bean
public void parse(Set configCandidates)
{
for(Iterator iterator = configCandidates.iterator(); iterator.hasNext();)
{
BeanDefinitionHolder holder = (BeanDefinitionHolder)iterator.next();
BeanDefinition bd = holder.getBeanDefinition();
try
{
if((bd instanceof AbstractBeanDefinition) && ((AbstractBeanDefinition)bd).hasBeanClass())
parse(((AbstractBeanDefinition)bd).getBeanClass(), holder.getBeanName());
else
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
}
protected final void parse(String className, String beanName)
throws IOException
{
MetadataReader reader = metadataReaderFactory.getMetadataReader(className);
processConfigurationClass(new ConfigurationClass(reader, beanName));
}
}
//扫描组件注解配置解析器
class ComponentScanAnnotationParser
{
public ComponentScanAnnotationParser(ResourceLoader resourceLoader, Environment environment, BeanNameGenerator beanNameGenerator, BeanDefinitionRegistry registry)
{
this.resourceLoader = resourceLoader;
this.environment = environment;
this.beanNameGenerator = beanNameGenerator;
this.registry = registry;
}
//解析注解配置
public Set parse(AnnotationAttributes componentScan, String declaringClass)
{
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry, componentScan.getBoolean("useDefaultFilters"));
Assert.notNull(environment, "Environment must not be null");
scanner.setEnvironment(environment);
Assert.notNull(resourceLoader, "ResourceLoader must not be null");
scanner.setResourceLoader(resourceLoader);
Class generatorClass = componentScan.getClass("nameGenerator");
boolean useInheritedGenerator = org/springframework/beans/factory/support/BeanNameGenerator.equals(generatorClass);
scanner.setBeanNameGenerator(useInheritedGenerator ? beanNameGenerator : (BeanNameGenerator)BeanUtils.instantiateClass(generatorClass));
ScopedProxyMode scopedProxyMode = (ScopedProxyMode)componentScan.getEnum("scopedProxy");
if(scopedProxyMode != ScopedProxyMode.DEFAULT)
{
scanner.setScopedProxyMode(scopedProxyMode);
} else
{
Class resolverClass = componentScan.getClass("scopeResolver");
scanner.setScopeMetadataResolver((ScopeMetadataResolver)BeanUtils.instantiateClass(resolverClass));
}
//包含注解类
AnnotationAttributes aannotationattributes[] = componentScan.getAnnotationArray("includeFilters");
int i = aannotationattributes.length;
for(int j = 0; j < i; j++)
{
AnnotationAttributes filter = aannotationattributes[j];
TypeFilter typeFilter;
for(Iterator iterator = typeFiltersFor(filter).iterator(); iterator.hasNext(); scanner.addIncludeFilter(typeFilter))
typeFilter = (TypeFilter)iterator.next();
}
//剔除注解类
aannotationattributes = componentScan.getAnnotationArray("excludeFilters");
i = aannotationattributes.length;
for(int k = 0; k < i; k++)
{
AnnotationAttributes filter = aannotationattributes[k];
TypeFilter typeFilter;
for(Iterator iterator1 = typeFiltersFor(filter).iterator(); iterator1.hasNext(); scanner.addExcludeFilter(typeFilter))
typeFilter = (TypeFilter)iterator1.next();
}
List basePackages = new ArrayList();
Object aobj[] = componentScan.getStringArray("value");
int l = aobj.length;
for(int i1 = 0; i1 < l; i1++)
{
String pkg = aobj[i1];
if(StringUtils.hasText(pkg))
basePackages.add(pkg);
}
aobj = componentScan.getStringArray("basePackages");
l = aobj.length;
for(int j1 = 0; j1 < l; j1++)
{
String pkg = aobj[j1];
if(StringUtils.hasText(pkg))
basePackages.add(pkg);
}
aobj = componentScan.getClassArray("basePackageClasses");
l = aobj.length;
for(int k1 = 0; k1 < l; k1++)
{
Class clazz = aobj[k1];
basePackages.add(ClassUtils.getPackageName(clazz));
}
//扫描基本包
return scanner.doScan(StringUtils.toStringArray(basePackages));
}
}
//ClassPathBeanDefinitionScanner,bean定义扫描
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider
{
protected transient Set doScan(String basePackages[])
{
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set beanDefinitions = new LinkedHashSet();
String as[] = basePackages;
int i = as.length;
label0:
for(int j = 0; j < i; j++)
{
String basePackage = as[j];
Set candidates = findCandidateComponents(basePackage);
Iterator iterator = candidates.iterator();
do
{
if(!iterator.hasNext())
continue label0;
BeanDefinition candidate = (BeanDefinition)iterator.next();
ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(candidate);
//设置bean作用域
candidate.setScope(scopeMetadata.getScopeName());
String beanName = beanNameGenerator.generateBeanName(candidate, registry);
if(candidate instanceof AbstractBeanDefinition)
//bean自动注入auotwired处理
postProcessBeanDefinition((AbstractBeanDefinition)candidate, beanName);
if(candidate instanceof AnnotatedBeanDefinition)
//处理lazy等注解
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition)candidate);
if(checkCandidate(beanName, candidate))
{
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, registry);
beanDefinitions.add(definitionHolder);
registerBeanDefinition(definitionHolder, registry);
}
} while(true);
}
return beanDefinitions;
}
//bean自动注入@auotwired处理
protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName)
{
beanDefinition.applyDefaults(beanDefinitionDefaults);
if(autowireCandidatePatterns != null)
beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(autowireCandidatePatterns, beanName));
}
}
//Servlet上下文监听器
public interface ServletContextListener
extends EventListener
{
public abstract void contextInitialized(ServletContextEvent servletcontextevent);
public abstract void contextDestroyed(ServletContextEvent servletcontextevent);
}
//上下文配置文件资源
public class ClassPathResource extends AbstractFileResolvingResource
{
//构遭上下文配置文件资源
public ClassPathResource(String path, ClassLoader classLoader)
{
Assert.notNull(path, "Path must not be null");
String pathToUse = StringUtils.cleanPath(path);
if(pathToUse.startsWith("/"))
pathToUse = pathToUse.substring(1);
this.path = pathToUse;
this.classLoader = classLoader == null ? ClassUtils.getDefaultClassLoader() : classLoader;
}
//解决上下文配置文件URL
protected URL resolveURL()
{
if(clazz != null)
return clazz.getResource(path);
if(classLoader != null)
return classLoader.getResource(path);
else
return ClassLoader.getSystemResource(path);
}
//获取上下文配置文件输入流
public InputStream getInputStream()
throws IOException
{
InputStream is;
if(clazz != null)
is = clazz.getResourceAsStream(path);
else
if(classLoader != null)
is = classLoader.getResourceAsStream(path);
else
is = ClassLoader.getSystemResourceAsStream(path);
if(is == null)
throw new FileNotFoundException((new StringBuilder()).append(getDescription()).append(" cannot be opened because it does not exist").toString());
else
return is;
}
//获取上下文配置文件URL
public URL getURL()
throws IOException
{
URL url = resolveURL();
if(url == null)
throw new FileNotFoundException((new StringBuilder()).append(getDescription()).append(" cannot be resolved to URL because it does not exist").toString());
else
return url;
}
//创建相对路径上下文配置文件资源
public Resource createRelative(String relativePath)
{
String pathToUse = StringUtils.applyRelativePath(path, relativePath);
return new ClassPathResource(pathToUse, classLoader, clazz);
}
//获取配置文件名
public String getFilename()
{
return StringUtils.getFilename(path);
}
private final String path;//路径
private ClassLoader classLoader;//上下文加载类
private Class clazz;
}
//属性配置文件加载工具
public abstract class PropertiesLoaderUtils
{
//加载配置文件
public static Properties loadProperties(Resource resource)
throws IOException
{
Properties props = new Properties();
fillProperties(props, resource);
return props;
}
//填充配置属性
public static void fillProperties(Properties props, Resource resource)
throws IOException
{
InputStream is = resource.getInputStream();
String filename = resource.getFilename();
if(filename != null && filename.endsWith(".xml"))
props.loadFromXML(is);
else
props.load(is);
is.close();
is.close();
}
private static final String XML_FILE_EXTENSION = ".xml";
}
//Properties
public class Properties extends Hashtable
{
//从XML文件输入流加载配置文件
public synchronized void loadFromXML(InputStream inputstream)
throws IOException, InvalidPropertiesFormatException
{
if(inputstream == null)
{
throw new NullPointerException();
} else
{
XMLUtils.load(this, inputstream);
inputstream.close();
return;
}
}
}
//ServletContextEvent
public class ServletContextEvent extends EventObject
{
public ServletContextEvent(ServletContext source)
{
super(source);
}
public ServletContext getServletContext()
{
return (ServletContext)super.getSource();
}
}
//ApplicationContext
public interface ApplicationContext
extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver
{
public abstract String getId();
public abstract String getApplicationName();
public abstract String getDisplayName();
public abstract long getStartupDate();
public abstract ApplicationContext getParent();
public abstract AutowireCapableBeanFactory getAutowireCapableBeanFactory()
throws IllegalStateException;
}
//WebApplicationContext
public interface WebApplicationContext
extends ApplicationContext
{
public abstract ServletContext getServletContext();
public static final String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = (new StringBuilder()).append(org/springframework/web/context/WebApplicationContext.getName()).append(".ROOT").toString();
public static final String SCOPE_REQUEST = "request";
public static final String SCOPE_SESSION = "session";
public static final String SCOPE_GLOBAL_SESSION = "globalSession";
public static final String SCOPE_APPLICATION = "application";
public static final String SERVLET_CONTEXT_BEAN_NAME = "servletContext";
public static final String CONTEXT_PARAMETERS_BEAN_NAME = "contextParameters";
public static final String CONTEXT_ATTRIBUTES_BEAN_NAME = "contextAttributes";
}
//ConfigurableWebApplicationContext
public interface ConfigurableWebApplicationContext
extends WebApplicationContext, ConfigurableApplicationContext
{
public abstract void setServletContext(ServletContext servletcontext);
public abstract void setServletConfig(ServletConfig servletconfig);
public abstract ServletConfig getServletConfig();
public abstract void setNamespace(String s);
public abstract String getNamespace();
public abstract void setConfigLocation(String s);
public abstract void setConfigLocations(String as[]);
public abstract String[] getConfigLocations();
public static final String APPLICATION_CONTEXT_ID_PREFIX = (new StringBuilder()).append(org/springframework/web/context/WebApplicationContext.getName()).append(":").toString();
public static final String SERVLET_CONFIG_BEAN_NAME = "servletConfig";
}
//StandardServletEnvironment
public class StandardServletEnvironment extends StandardEnvironment
implements ConfigurableWebEnvironment
{
public void initPropertySources(ServletContext servletContext, ServletConfig servletConfig)
{
//初始化ServletPropertySources
WebApplicationContextUtils.initServletPropertySources(getPropertySources(), servletContext, servletConfig);
}
public static final String SERVLET_CONTEXT_PROPERTY_SOURCE_NAME = "servletContextInitParams";
public static final String SERVLET_CONFIG_PROPERTY_SOURCE_NAME = "servletConfigInitParams";
public static final String JNDI_PROPERTY_SOURCE_NAME = "jndiProperties";
}
//WebApplicationContext工具类
public abstract class WebApplicationContextUtils
{
//初始化servletContextInitParams
public static void initServletPropertySources(MutablePropertySources propertySources, ServletContext servletContext, ServletConfig servletConfig)
{
Assert.notNull(propertySources, "propertySources must not be null");
if(servletContext != null && propertySources.contains("servletContextInitParams") && (propertySources.get("servletContextInitParams") instanceof org.springframework.core.env.PropertySource.StubPropertySource))
propertySources.replace("servletContextInitParams", new ServletContextPropertySource("servletContextInitParams", servletContext));
if(servletConfig != null && propertySources.contains("servletConfigInitParams") && (propertySources.get("servletConfigInitParams") instanceof org.springframework.core.env.PropertySource.StubPropertySource))
propertySources.replace("servletConfigInitParams", new ServletConfigPropertySource("servletConfigInitParams", servletConfig));
}
}
//ApplicationContextInitializer
public interface ApplicationContextInitializer
{
public abstract void initialize(ConfigurableApplicationContext configurableapplicationcontext);
}
//bean工具类
public abstract class BeanUtils
{
//初始化Class
public static Object instantiateClass(Class clazz)
throws BeanInstantiationException
{
Assert.notNull(clazz, "Class must not be null");
if(clazz.isInterface())
throw new BeanInstantiationException(clazz, "Specified class is an interface");
return instantiateClass(clazz.getDeclaredConstructor(new Class[0]), new Object[0]);
NoSuchMethodException ex;
ex;
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
//根据构造函数初始化Object
public static transient Object instantiateClass(Constructor ctor, Object args[])
throws BeanInstantiationException
{
Assert.notNull(ctor, "Constructor must not be null");
ReflectionUtils.makeAccessible(ctor);
return ctor.newInstance(args);
InstantiationException ex;
ex;
throw new BeanInstantiationException(ctor.getDeclaringClass(), "Is it an abstract class?", ex);
ex;
throw new BeanInstantiationException(ctor.getDeclaringClass(), "Is the constructor accessible?", ex);
ex;
throw new BeanInstantiationException(ctor.getDeclaringClass(), "Illegal arguments for constructor", ex);
ex;
throw new BeanInstantiationException(ctor.getDeclaringClass(), "Constructor threw exception", ex.getTargetException());
}
}
总结:
Spring上下文加载监听,在静态语句块中加载配置文件contextConfigLocation,
然后初始化ServletContext,以便spring容器可以直接访问web容器上下文,注册bean后置处理器,构造bean,初始化消息源,监听器;在构造bean的过程中通过ConfigurationClassParser来解析bean,处理注解,IOC等。