Spring容器初始化
本文使用的是Spring 5.1.7版本
写在前面:我们看源码一般有3种方式。
- 第一种直接用class文件,IDEA会帮我们反编译成看得懂的java代码
- 第二种是用maven的download Sources
- 第三种是直接下载源码编译
如果随便看看,那么第二种就行了。如果想仔细研究,可以选第三种,这样可以给代码加注释,或者修改一些东西等等。
Spring源码构建
- 下载源码(github)
- 安装gradle
- 导入项目
- 编译工程(顺序:core->xom->context->beans->aspects->aop)
- 编译方法:工程->tasks->compileTestJava
- 编译完成后,新建一个测试module,用gradle的方式,build.gradle为:
group \'org.springframework\'version \'5.1.21.BUILD-SNAPSHOT\'apply plugin: \'java\'sourceCompatibility = 1.8repositories {mavenCentral()}dependencies {compile(project(":spring-context"))testCompile group: \'junit\', name: \'junit\', version: \'4.12\'}
如果运行报错,需要设置IDEA。需要将Preferences > Build, Execution, Deployment > Build Tools > Gradle > Runner里的 Delegate IDE build/run actions to gradle勾选上。
Spring IOC容器初始化的关键环节就在AbstractApplicationContext的refresh方法中。
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {//第一步:刷新前的预处理prepareRefresh();// 第二步:获取BeanFactory;加载BeanDefition并注册到BeanDefitionRegistryConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// 第三步:BeanFactory的预准备工作prepareBeanFactory(beanFactory);try {// 第四步:BeanFactory准备工作完成之后进行的后置处理postProcessBeanFactory(beanFactory);// 第五步:实例化并调用实现了BeanFactoryPostProcessor接口的BeaninvokeBeanFactoryPostProcessors(beanFactory);// 第六步:注册BeanPostProcessor,在创建bean的前后等执行。registerBeanPostProcessors(beanFactory);// 第七步:初始化MessageSource组件(做国际化功能;消息绑定,消息解析)initMessageSource();// 第八步:初始化事件派发器initApplicationEventMulticaster();//第九步:提供给子类重写,容器刷新的适合可以自定义逻辑onRefresh();// 第十步:注册应用监听器。就是注册实现了ApplicationListener接口的监听器beanregisterListeners();// 第十一步:初始化所有剩下的非懒加载的单例bean,//填充属性//初始化方法调用//调用BeanPostProcessor对bean进行后置处理finishBeanFactoryInitialization(beanFactory);// 第十二步:完成context的刷新。主要是调用LifecycleProcessor的onRefresh方法,并且发布ContextRefreshedEvent事件finishRefresh();}catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset \'active\' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}finally {// Reset common introspection caches in Spring\'s core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();}}}
接下来我们分析第二步中的两个子流程:
2.1. 获取BeanFactory子流程
时序图如下:
2.2. BeanDefinition加载解析及注册⼦流程
BeanDefinition加载流程入口在AbstractRefreshableApplicationContext#refreshBeanFactory ⽅法中,会调用到loadBeanDefinitions方法,这个方法最终会由XmlBeanDefinitionReader的loadBeanDefinitions方法来完成。然后会调用它自己的doLoadBeanDefinitions方法。
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)throws BeanDefinitionStoreException {try {//读取xml信息,将xml信息保存到Document中Document doc = doLoadDocument(inputSource, resource);//解析doc,封装到BeanDefinition对象并进行注册int count = registerBeanDefinitions(doc, resource);if (logger.isDebugEnabled()) {logger.debug("Loaded " + count + " bean definitions from " + resource);}return count;}//省略部分代码....
继续跟踪registerBeanDefinitions方法。
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();//获取已有的BeanDefinition的数量int countBefore = getRegistry().getBeanDefinitionCount();//注册BeanDefinitionsdocumentReader.registerBeanDefinitions(doc, createReaderContext(resource));//返回新注册的BeanDefinition的数量return getRegistry().getBeanDefinitionCount() - countBefore;}
它又交由documentReader来执行registerBeanDefinitions方法。documentReader接收后调用本类的doRegisterBeanDefinitions来执行。这个方法里我们需要关注parseBeanDefinitions.preProcessXml和postProcessXml都是留给子类实现的。
protected void doRegisterBeanDefinitions(Element root) {//省略部分代码...preProcessXml(root);parseBeanDefinitions(root, this.delegate);postProcessXml(root);this.delegate = parent;}
跟踪parseBeanDefinitions方法,可以看到由DefaultBeanDefinitionDocumentReader#parseDefaultElement在进行解析
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {//import处理if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {importBeanDefinitionResource(ele);}//alias处理else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {processAliasRegistration(ele);}//解析bean元素else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {processBeanDefinition(ele, delegate);}//嵌套bean处理else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {// recursedoRegisterBeanDefinitions(ele);}}
最后跟踪processBeanDefinition的代码
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {//解析bean元素为BeanDefinition,但是此时使用BeanDefinitionHolder又包装了一层BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);if (bdHolder != null) {bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);try {// 完成BeanDefinition的注册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));}}
到这里就完成了BeanDefinition的注册。我们发现,所谓的注册就是把 XML 中定义的Bean信息封装为BeanDefinition对象之后放⼊⼀个Map中。
this.beanDefinitionMap.put(beanName, beanDefinition);
简略的时序图如下:
接下来我们分析一下Bean创建的流程。Bean创建是在refresh主流程中的第十一步里面。
11.1 Bean创建子流程
我们进入finishBeanFactoryInitialization方法。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {//省略部分代码...String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);for (String weaverAwareName : weaverAwareNames) {getBean(weaverAwareName);}// Stop using the temporary ClassLoader for type matching.beanFactory.setTempClassLoader(null);// Allow for caching all bean definition metadata, not expecting further changes.beanFactory.freezeConfiguration();// 实例化所有非懒加载的beanbeanFactory.preInstantiateSingletons();}
跟踪preInstantiateSingletons方法
public void preInstantiateSingletons() throws BeansException {if (logger.isTraceEnabled()) {logger.trace("Pre-instantiating singletons in " + this);}// Iterate over a copy to allow for init methods which in turn register new bean definitions.// While this may not be part of the regular factory bootstrap, it does otherwise work fine.List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);// 遍历所有的beanNamefor (String beanName : beanNames) {RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {//如果是工厂bean,即实现了FactoryBean接口if (isFactoryBean(beanName)) {Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);if (bean instanceof FactoryBean) {FactoryBean<?> factory = (FactoryBean<?>) bean;boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}}else {//实例化当前beangetBean(beanName);}}}//省略...}
我们发现不管是工厂Bean,还是普通Bean都会调用getBean(beanName);方法。然后调用到doGetBean方法。
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)throws BeansException {String beanName = transformedBeanName(name);Object bean;// 从缓存中拿Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {if (logger.isTraceEnabled()) {if (isSingletonCurrentlyInCreation(beanName)) {logger.trace("Returning eagerly cached instance of singleton bean \'" + beanName +"\' that is not fully initialized yet - a consequence of a circular reference");}else {logger.trace("Returning cached instance of singleton bean \'" + beanName + "\'");}}bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}else {//如果已经有创建过程中的同beanName的bean,抛异常if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}// 从parentBeanFactory里找对应的beanBeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {// Not found -> check parent.String nameToLookup = originalBeanName(name);if (parentBeanFactory instanceof AbstractBeanFactory) {return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);}else if (args != null) {// Delegation to parent with explicit args.return (T) parentBeanFactory.getBean(nameToLookup, args);}else if (requiredType != null) {// No args -> delegate to standard getBean method.return parentBeanFactory.getBean(nameToLookup, requiredType);}else {return (T) parentBeanFactory.getBean(nameToLookup);}}if (!typeCheckOnly) {//打一个已创建的标记markBeanAsCreated(beanName);}try {RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinition(mbd, beanName, args);// 保证当前bean所依赖的bean的初始化String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {for (String dep : dependsOn) {if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between \'" + beanName + "\' and \'" + dep + "\'");}registerDependentBean(dep, beanName);try {getBean(dep);}catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"\'" + beanName + "\' depends on missing bean \'" + dep + "\'", ex);}}}//创建bean// 单例beanif (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, () -> {try {//具体的创建bean逻辑return createBean(beanName, mbd, args);}catch (BeansException ex) {// Explicitly remove instance from singleton cache: It might have been put there// eagerly by the creation process, to allow for circular reference resolution.// Also remove any beans that received a temporary reference to the bean.destroySingleton(beanName);throw ex;}});bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}//多例beanelse if (mbd.isPrototype()) {// It\'s a prototype -> create a new instance.Object prototypeInstance = null;try {beforePrototypeCreation(beanName);prototypeInstance = createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}else {String scopeName = mbd.getScope();if (!StringUtils.hasLength(scopeName)) {throw new IllegalStateException("No scope name defined for bean ´" + beanName + "\'");}Scope scope = this.scopes.get(scopeName);if (scope == null) {throw new IllegalStateException("No Scope registered for scope name \'" + scopeName + "\'");}try {Object scopedInstance = scope.get(beanName, () -> {beforePrototypeCreation(beanName);try {return createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}});bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);}catch (IllegalStateException ex) {throw new BeanCreationException(beanName,"Scope \'" + scopeName + "\' is not active for the current thread; consider " +"defining a scoped proxy for this bean if you intend to refer to it from a singleton",ex);}}}catch (BeansException ex) {cleanupAfterBeanCreationFailure(beanName);throw ex;}}// 检查所需类型是否与实际bean实例的类型匹配。if (requiredType != null && !requiredType.isInstance(bean)) {try {T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);if (convertedBean == null) {throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());}return convertedBean;}catch (TypeMismatchException ex) {if (logger.isTraceEnabled()) {logger.trace("Failed to convert bean \'" + name + "\' to required type \'" +ClassUtils.getQualifiedName(requiredType) + "\'", ex);}throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());}}return (T) bean;}
可以看到经过一些判断和校验,会调createBean方法去创建bean,然后调用doCreateBean去完成创建。
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {// Instantiate the bean.BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {//创建bean实例,但是尚未设置属性instanceWrapper = createBeanInstance(beanName, mbd, args);}Object bean = instanceWrapper.getWrappedInstance();Class<?> beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}//允许后处理器修改合并的bean定义synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);}catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Post-processing of merged bean definition failed", ex);}mbd.postProcessed = true;}}//急切地缓存单例,以便能够解析循环引用//即使由BeanFactoryAware等生命周期接口触发。boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isTraceEnabled()) {logger.trace("Eagerly caching bean \'" + beanName +"\' to allow for resolving potential circular references");}addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}// Initialize the bean instance.Object exposedObject = bean;try {//设置属性populateBean(beanName, mbd, instanceWrapper);//应用初始化方法,调用BeanPostProcessor后置处理器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<>(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 " +"\'getBeanNamesForType\' 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;}
在上述的方法中会先实例化一个bean,然后注入property里面配置的属性,最后执行初始化相关方法。
简单时序图: