赞
踩
一个简单的xml配置入口函数:
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Object object = applicationContext.getBean("json");
System.out.println(object.toString());
从这个入口出发,即ClassPathXmlApplicationContext的构造方法,可以窥见Spring容器启动的过程。但是Spring太庞大了,直接进去看源码容易绕晕。先放几张类图:
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处理。具体执行顺序为:
这里涉及到的排序,即优先级顺序为PriorityOrdered一级优先,Ordered二级优先,PriorityOrdered, Ordered是两个接口。同级按照order值由大到小排序。
(6) AbstractApplicationContext.registerBeanPostProcessors
注册BeanPostProcessor。和执行BeanFactoryPostProcessor的逻辑有点类似,也用到了排序,不过这里只是注册到BeanFactory中。注册顺序为:
这里手动设置一个BeanPostProcessorChecker,将当前beanPostProcessor的数量传入构造方法。
(7) AbstractApplicationContext.initMessageSource
设置messageSource,用来处理message,国际化文本等,默认为DelegatingMessageSource
(8) AbstractApplicationContext.initApplicationEventMulticaster
设置应用事件广播器,默认为SimpleApplicationEventMulticaster
(9) AbstractApplicationContext.onRefresh
此方法没有实现。
(10) AbstractApplicationContext.registerListeners
注册ApplicationListener类型的监听处理器到(8)创建的ApplicationEventMulticaster,注册顺序为:
(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并行通知,并且向父上下文也通知。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。