Spring源码:加载流程概览
一个简单的xml配置入口函数:
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Object object = applicationContext.getBean("json");
System.out.println(object.toString());
从这个入口出发,即ClassPathXmlApplicationContext的构造方法,可以窥见Spring容器启动的过程。但是Spring太庞大了,直接进去看源码容易绕晕。先放几张类图:
- ApplicationContext是一个接口,但不是顶层接口,他继承自HierarchicalBeanFactory, ListableBeanFactory, ApplicationEventPublisher, ResourcePatternResolver, MessageSource接口。
ClassPathXmlApplication(String configLocation)
跟踪构造方法:
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent); (1)
setConfigLocations(configLocations); (2)
if (refresh) {
refresh(); (3)
}
}
(1) 中调用父类构造函数,即AbstractApplicationContext的属性parent父上下文, resourcePatternResolver进行初始化。
(2) 设置配置文件路径,在AbstractRefereshableConfigApplicationContext中的属性String[] configLocations。
(3) 刷新上下文,也就是最重要的构建Spring的方法了。refresh方法是继承自AbstractApplicationContext,比较重要直接贴代码:
AbstractApplicationContext.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;
}
}
}
可以看到,基本都是protected方法,子类可以覆盖自己的行为; 而且通过startupShutdownMonitor上对象锁。接下来就挨个看看这些方法。
(1) AbstractApplicationContext.prepareRefresh()
准备刷新上下文,记录日志,active标志。
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
synchronized (this.activeMonitor) {
this.active = true;
}
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
}
最后的logger.info("Refreshing "+this)
会打印出当前上下文对象的实例,可查看toString源码,默认为Class@hash。不过在Spring mvc项目中会将displayName设成"Root WebApplicationContext",看不到实际的上下文类型。
(2) AbstractApplicationContext.obtainFreshBeanFactory()
获取并初始化BeanFactory,加载BeanDefinition。
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
其中refreshBeanFactory即设置BeanFactory了。
AbstractRefreshableApplicationContext.refreshBeanFactory()
@Override
protected final void refreshBeanFactory() throws BeansException {
//销毁先前的BeanFactory
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory(); //创建DefaultListableBeanFactory实例
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory); //初始化配置
loadBeanDefinitions(beanFactory); //加载BeanDefinition,即读取xml文件中的bean为BeanDefinition
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
createBeanFactory创建DefaultListableBeanFactory类型的BeanFactory,并将继承自AbstractBeanFactory的parentBeanFactory属性设置为null。在父类AbstractAutowireCapableBeanFactory构造方法中指定了三个忽略的依赖接口:
public AbstractAutowireCapableBeanFactory() {
super();
ignoreDependencyInterface(BeanNameAware.class);
ignoreDependencyInterface(BeanFactoryAware.class);
ignoreDependencyInterface(BeanClassLoaderAware.class);
}
将BeanNameAware三个接口添加到ignoredDependencyInterfaces属性中,尚不清楚这个属性干啥的。Aware系列接口一般表示对什么上下文有感知,例如实现BeanFactoryAware接口可以讲BeanFactory注入,实现ApplicationContextAware可以将ApplicationContext注入。
customizeBeanFactory进行一些初始化配置,例如循环引用,@Qualifier解析器等。
loadBeanDefinitions加载BeanDefinition到BeanFactory中。XmlBeanDefinitionReader的loadBeanDefinitions方法从先前设置的Resource[] configResources和String[] configLocations读取配置,这里只有configLocations有值。如果没有设置configLocations,Spring有一个默认值,查看源码就看到了,默认为/WEB-INF/${namespace}.xml,而且默认的namespace=applicationContext。
DefaultBeanDefinitionDocumentReader.processBeanDefinition
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
通过BeanDefinitionParserDelegate将Element元素解析为BeanDefinitionHolder,并注册到Registry中。BeanDefinitionRegistry是一个用于注册BeanDefinition的接口,这里的Registry实际上就是前面创建的DefaultListableBeanFactory,实现了BeanDefinitionRegistry接口,把所有的BeanDefinition和名称注册到下面两个属性中。
/** Map of bean definition objects, keyed by bean name */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>();
/** List of bean definition names, in registration order */
private final List<String> beanDefinitionNames = new ArrayList<String>();
加载BeanDefinition后,将BeanFactory实例赋值给AbstractRefreshableApplicationContext的beanFactory属性,即refresh完成。(synchronized this.beanFactoryMonitor,Spring好多操作都要上同步锁)
(3) AbstractApplicationContext.prepareBeanFactory
对BeanFactory初始化操作。
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this));
// 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 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);
//... 以及LoadTimeWeaverProcessor, 系统属性和环境变量。
其中的ApplicationContextAwareProcessor是一个BeanPostProcessor,处理实现了部分Aware接口的Bean,将上下文注入。
(4) AbstractApplicationContext.postProcessBeanFactory
此方法没有实现。
(5) AbstractApplicationContext.invokeBeanFactoryPostProcessors
执行BeanFactoryPostProcessor处理。具体执行顺序为:
- AbstractApplicationContext.beanFactoryPostProcessors中实现了BeanDefinitionRegistryPostProcessor的processor,执行postProcessBeanDefinitionRegistry方法
- beanFactory中实现了BeanDefinitionRegistryPostProcessor的processor, 按照Order排序,执行postProcessBeanDefinitionRegistry方法
- AbstractApplicationContext.beanFactoryPostProcessors中实现了BeanDefinitionRegistryPostProcessor的processor,执行postProcessFactory方法
- beanFactory中实现了BeanDefinitionRegistryPostProcessor的processor, 按照Order排序,执行postProcessFactory方法
- AbstractApplicationContext.beanFactoryPostProcessors中未实现BeanDefinitionRegistryPostProcessor的processor,执行postProcessFactory方法
- beanFactory中实现了BeanFactoryPostProcessor的processor,按照Order排序,依次执行PriorityOrderedPostProcessor、OrderedPostProcessor、NonOrderedPostProcessor的postProcessFactory方法
这里涉及到的排序,即优先级顺序为PriorityOrdered一级优先,Ordered二级优先,PriorityOrdered, Ordered是两个接口。同级按照order值由大到小排序。
(6) AbstractApplicationContext.registerBeanPostProcessors
注册BeanPostProcessor。和执行BeanFactoryPostProcessor的逻辑有点类似,也用到了排序,不过这里只是注册到BeanFactory中。注册顺序为:
- beanFactory中实现了BeanPostProcessor,PriorityOrdered的processor,按优先级顺序注册
- beanFactory中实现了BeanPostProcessor,Ordered的processor,按优先级顺序注册
- beanFactory中实现了BeanPostProcessor的processor,按顺序注册
- beanFactory中实现了MergedBeanDefinitionPostProcessor的processor(内部processor),按优先级顺序注册
这里手动设置一个BeanPostProcessorChecker,将当前beanPostProcessor的数量传入构造方法。
(7) AbstractApplicationContext.initMessageSource
设置messageSource,用来处理message,国际化文本等,默认为DelegatingMessageSource
(8) AbstractApplicationContext.initApplicationEventMulticaster
设置应用事件广播器,默认为SimpleApplicationEventMulticaster
(9) AbstractApplicationContext.onRefresh
此方法没有实现。
(10) AbstractApplicationContext.registerListeners
注册ApplicationListener类型的监听处理器到(8)创建的ApplicationEventMulticaster,注册顺序为:
- AbstractApplicationContext.applicationListeners
- beanFactory中实现了ApplicationListener的listener
(11) AbstractApplicationContext.finishBeanFactoryInitialization
真正完成Bean的初始化,BeanPostProcessor执行等。
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();
}
Bean初始化逻辑主要在preInstantiateSingletons中,对beanDefinitionMap同步锁初始化。最终调用AbstractAutowireCapableBeanFactory.doCreateBean方法,比较长。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
applyMergedBeanDefinitionPostProcessors这里,执行MergedBeanDefinitionPostProcessor,即前面提到的“内部处理器”。MergedBeanDefinitionPostProcessor的一个实现类是AutowiredAnnotationBeanPostProcessor,处理@Autowired注解的属性和方法,将依赖的对象或者参数注入。
populateBean填充属性。
initializeBean调用Aware方法、BeanPostProcessor、初始化方法。
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
((InitializingBean) bean).afterPropertiesSet();
return null;
}
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null) {
String initMethodName = mbd.getInitMethodName();
if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
可以看到,初始化方法是先调用afterPropertiesSet,然后在调用自定义的init-method方法。
(12) AbstractApplicationContext.finishRefresh
上下文刷新完成,执行LifecycleProcessor.onRefresh方法,发布刷新完成的事件。
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));
}
initLifecycleProcessor注册LifecycleProcessor,默认为DefaultLifecycleProcessor。
getLifecycleProcessor().onRefresh将实现LifeCycle的Bean执行start方法。
publishEvent发布事件,使applicationEventMulticaster向applicationListeners通知事件。而且这里通过Spring的taskExecutor并行通知,并且向父上下文也通知。
坑点:afterProperties开启线程初始化,但依赖的Bean还没有初始化,死锁发生在synchronized singletonObjects。