跟着我吃透spring核心源码
前言
springmvc,springboot,springcloud以及他们很多配套框架,比如各种stater,springsecurity等所有的基础是spring,作为spring家族的源码分析最基础的部分,这篇文章把spring给大家尽量用最简单的方法,把主要流程讲清楚。为后续的springboot,springcloud,以及其他相关框架分析打下基础。
spring框架简单的例子
引入依赖:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.11.RELEASE</version> </dependency>
定义一个接口:
public interface DemoService { String getData(); }
定义接口实现类:
public class DemoServiceImpl implements DemoService { public String getData() { return "hello world"; } }
接下来,我们在 resources 目录新建一个配置文件,文件随意,这里命名成application.xml:
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire="byName"> <bean id="demoService" class="com.wang.example.DemoServiceImpl"/> </beans>
这样,我们就可以跑起来了:
public class App { public static void main(String[] args) { // 用我们的配置文件来启动一个 ApplicationContext ApplicationContext context = new ClassPathXmlApplicationContext("classpath:application.xml"); System.out.println("context 启动成功"); // 从 context 中取出我们的 Bean,这是spring的方式,不用去new DemoServiceImpl DemoService demoService = context.getBean(demoService.class); // 这句将输出: hello world System.out.println(demoService.getData()); } }
这就是一个最简单使用spring的例子,可能很多直接用springboot开发的人都已经不了解这个了,但是如果想要分析spring源码首先要知道它怎么用,如果不知道怎么用,源码分析就无从谈起了。
接下来以这个例子为入口,一起分析下spring的流程。
分析之前我先简单说下流程,后续验证下spring源码的整体流程是不是这样:
会扫描指定的配置文件“classpath:application.xml”,然后扫描解析xml文件,按照里面的节点信息比如“<bean id="demoService"/>”,实例化对应的对象,对象信息就是<bean>节点定义的信息,最后放入到map集合中,叫做“容器”。
后续“context.getBean(demoService.class)”方法其实就是从容器(前面的map集合)中获取到的实例。
这里的map集合其实就是spring容器,对应spring中FactoryBean这个类,看名字就知道它是管理bean的一个类。
看一下BeanFactory的部分源码:
public interface BeanFactory { String FACTORY_BEAN_PREFIX = "&"; Object getBean(String var1) throws BeansException; <T> T getBean(String var1, Class<T> var2) throws BeansException; Object getBean(String var1, Object... var2) throws BeansException; <T> T getBean(Class<T> var1) throws BeansException; <T> T getBean(Class<T> var1, Object... var2) throws BeansException; ... }
可以看到它是一个接口,里面定义了获取bean的各种方法,其实就是从map集合中获取的。上面例子中ApplicationContext和FactoryBean什么关系呢?
答案:FactoryBean是ApplicationContext的父类,所以ApplicationContext属于容器
上图是BeanFactory和ApplicationContext类继承关系,以及主要的BeanFactory子类,后续分析会涉及到这张类图,后续说到类图记得回到这里啊。
FileSystemXmlApplicationContext 构造函数需要一个 xml 配置文件在系统中的路径和ClassPathXmlApplicationContext功能差不多,都是扫描xml文件生成实例的容器。
AnnotationConfigApplicationContext 是用于扫描注解生成实例的容器,目前springboot都是用的这个,等到后续分析springboot源码的时候就可以看到了。
知道了类的大体继承关系后,下面开始分析代码:
ClassPathXmlApplicationContext:
public ClassPathXmlApplicationContext( String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException { super(parent); // 把配置文件的路径设置到ApplicationContext,供后续调用解析使用 setConfigLocations(configLocations); if (refresh) { // spring解析的核心方法 refresh(); } }
AbstractApplicationContext:
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 准备工作,记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符。不是 // 核心逻辑,知道就行了 prepareRefresh(); // 这个是核心逻辑的第一步, // 1. new DefaultListableBeanFactory() 这是核心的容器BeanFactory,都是通过它 // 获取对应的实例对象的 // 2. loadBeanDefinitions,解析配置文件application.xml中的实例对象,并生成 // 一个一个的BeanDefinition,放入Map<String, BeanDefinition> 的一个map中, // 其中string是bean的名字,BeanDefinition是描述了一个bean类。 // 这个时候还没有开始实例化的操作,只是把类的信息解析到了BeanDefinition中。 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 做一些准备工作给Beanfactory,其实就是给beanFactory进行了一系列的配置工作,为 // 后续操作做准备。比如:ClassLoader 和post-processors等 prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. // 这里主要提供给子类的一个扩展点,主要是添加BeanPostProcessor,供子类使用,在 // 后续finishBeanFactoryInitialization方法中完成实例化后会调用 postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. // 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别 // 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization // 后续会在finishBeanFactoryInitialization中触发 registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // 初始化 ApplicationContext 的事件广播器,spring中的publicEvent核心方法就是它, // 用来发送事件通知的,监听器可以监听到发出的事件,这个在实际工作中是有用到的。 initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. // 钩子函数,供子类扩展使用的. // -------------------------------------------------------- // springboot中,就是有子类实现了这个方法,进而创建 // 出内嵌了tomcat容器,创建了WebServerStartStopLifecycle,供tomcat启动 // 这块会在我后续文章中说明 onRefresh(); // Check for listener beans and register them. // 注册各种Listeners,上面initApplicationEventMulticaster方法注册了广播器 // 最后发出的广播事件,都是被这里的监听器来监听的。 // -------------------------------------------------------- // springboot启动的时候,会通它做各种的初始化操作,关注我后面的文章 registerListeners(); // 这个是最重要的了,也是核心逻辑实例并初始化所有的singleton beans finishBeanFactoryInitialization(beanFactory); // 调用LifecycleProcessor的onRefresh()方法,并发送ContextRefreshedEvent事件。 // 收尾工作了属于。 // -------------------------------------------------------- // 对于springboot在上面的onRefresh方法中创建了WebServerStartStopLifecycle, // 在这一步会调用WebServerStartStopLifecycle的onRefresh方法,完成springboot内嵌 // tomcat容器的启动。 // 后面我会单独开一篇文章来讲springboot源码会提到这块,请关注我。 finishRefresh(); } .... } }
这是主要流程了,里面我都加了注释,和springboot相关的代码我也加了注释。为后续分析springboot源码的文章做准备,希望大家多多关注我后续的文章。
这里只分析spring相关的核心代码:
obtainFreshBeanFactory
finishBeanFactoryInitialization
obtainFreshBeanFactory流程分析
主要完成了创建bean容器,并注册对应的BeanDefinition到容器中
AbstractApplicationContext:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { // 创建新的 BeanFactory,加载 Bean 定义、注册 Bean refreshBeanFactory(); return getBeanFactory(); }
AbstractRefreshableApplicationContext:
protected final void refreshBeanFactory() throws BeansException { // 如果已经加载过 BeanFactory了,并销毁BeanFactory中所有 Bean,关闭 BeanFactory if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { // 创建BeanFactory,创建的子类是DefaultListableBeanFactory,为什么用这个子类? // 下面说 DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); // 设置 BeanFactory 的两个配置属性:是否允许 Bean 覆盖、是否允许循环引用 customizeBeanFactory(beanFactory); // 加载 Bean 到 BeanFactory 中 loadBeanDefinitions(beanFactory); //把容器设置给当前的ApplicationContext this.beanFactory = beanFactory; } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }
为什么用DefaultListableBeanFactory子类呢?再看下这个类图
DefaultListableBeanFactory几乎继承了所有的BeanFactory相关的类,它把祖祖辈辈的功能都继承下来了,它最牛逼了,所以就创建它了。
前面代码中也提到BeanDefinition,它是spring中很重要的一个类,保存了xml中bean类的定义信息,英文翻译过来也是这个意思“bean定义”,看下它的代码如下:
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement { // spring中创建类的方式 // singleton 只有一个实例,也即是单例模式。 // prototype访问一次创建一个实例,相当于new。 String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON; String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE; ... // 设置父 BeanName void setParentName(String parentName); // 获取父 BeanName String getParentName(); // 设置 Bean 的类名称 void setBeanClassName(String beanClassName); // 获取 Bean 的类名称 String getBeanClassName(); // 设置 bean 的 scope void setScope(String scope); String getScope(); // 设置是否懒加载 void setLazyInit(boolean lazyInit); boolean isLazyInit(); // 设置该 Bean 依赖的所有的 Bean,注意,这里的依赖不是指属性依赖(如 @Autowire 标记的), // 是 depends-on="" 属性设置的值。 void setDependsOn(String... dependsOn); // 返回该 Bean 的所有依赖 String[] getDependsOn(); // 设置该 Bean 是否可以注入到其他 Bean 中,只对根据类型注入有效, // 如果根据名称注入,即使这边设置了 false,也是可以的 void setAutowireCandidate(boolean autowireCandidate); // 该 Bean 是否可以注入到其他 Bean 中 boolean isAutowireCandidate(); // 主要的。同一接口的多个实现,如果不指定名字的话,Spring 会优先选择设置 primary 为 true 的 bean void setPrimary(boolean primary); // 是否是 primary 的 boolean isPrimary(); // 如果该 Bean 采用工厂方法生成,指定工厂名称。对工厂不熟悉的读者,请参加附录 void setFactoryBeanName(String factoryBeanName); // 获取工厂名称 String getFactoryBeanName(); // 指定工厂类中的 工厂方法名称 void setFactoryMethodName(String factoryMethodName); // 获取工厂类中的 工厂方法名称 String getFactoryMethodName(); // 构造器参数 ConstructorArgumentValues getConstructorArgumentValues(); // Bean 中的属性值,后面给 bean 注入属性值的时候会说到 MutablePropertyValues getPropertyValues(); // 是否 singleton boolean isSingleton(); // 是否 prototype boolean isPrototype(); // 如果这个 Bean 原生是抽象类,那么不能实例化 boolean isAbstract(); int getRole(); String getDescription(); String getResourceDescription(); BeanDefinition getOriginatingBeanDefinition(); }
可以看到BeanDefinition定义了bean的所有信息,通过它就能把一个bean实例化出来。
接着分析上面的代码:
主要就是如下两个方法了
customizeBeanFactory(beanFactory); loadBeanDefinitions(beanFactory)
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) { if (this.allowBeanDefinitionOverriding != null) { // 设置是否允许用一个同名的bean name覆盖bean类定义,来替换前面的一个。 // 如果允许就替换了,如果不允许就会抛个异常。 // spring中默认是true,允许。 beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding); } if (this.allowCircularReferences != null) { // 设置是否允许循环依赖,并自动解决这个问题。默认是true。 // 循环依赖就是类A依赖B,B里面通过依赖A,这就是循环依赖了。 // spring解决这个问题,思路就是用单例(好多教程叫缓存,无所谓了),就是第一次 // A实例化的时候会放到map容器中,因为依赖B,所以会再实例化B去,实例化 // B的时候发现B又依赖A,所有又去实例化A,这个时候发现A已经在map容器中存在了, // 所以就直接返回,这样就不会再继续循环下去了。 beanFactory.setAllowCircularReferences(this.allowCircularReferences); } }
继续分析loadBeanDefinitions,它是最主要的,解析了xml,并注册了BeanDefinition到容器中。
@Override protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { // 给BeanFactory实例化一个 XmlBeanDefinitionReader,看名字就知道 // 就是解析xml用的 XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); // Configure the bean definition reader with this context's // resource loading environment. beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); // 不重要,跳过 initBeanDefinitionReader(beanDefinitionReader); // 继续跟进它,主线逻辑 loadBeanDefinitions(beanDefinitionReader); }
loadBeanDefinitions调用最终会把beanDefinition注册到容器中
调用比较多,这个流程我用时序图画出来。
最后调用了这个方法,把BeanDefinition注册到容器中了。下面列出了核心方法。
@Override public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { ... BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName); // 如果已经存在了这个BeanDefinition if (existingDefinition != null) { // 检查是否允许覆盖 if (!isAllowBeanDefinitionOverriding()) { // 如果不允许覆盖就抛出异常,前面分析过这个属性了 throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition); } // 注册到容器中,这样就覆盖了原来的bean。 this.beanDefinitionMap.put(beanName, beanDefinition); } else { // 不存在该bean if (hasBeanCreationStarted()) { //已经开始创建流程了,用锁锁住,避免冲突 // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { // 放到容器中 this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; removeManualSingletonName(beanName); } } else { // 注册beanDefinition到容器中 this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); removeManualSingletonName(beanName); } this.frozenBeanDefinitionNames = null; } ... }
至此,终于把obtainFreshBeanFactory流程讲完了。
接下来继续finishBeanFactoryInitialization核心流程,把类实例化出来,代码如下:
AbstractApplicationContext
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // 实例化名字为 conversionService 的 Bean。 // 这块挺常用,后面单独说下,beanFactory.getBean这个方法会触发实例化操作。 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); // 冻结beanDefinition信息,这个时候要开始实例化了,不期望再修改这些信息了。 // 主要就是设置了一个冻结标示 beanFactory.freezeConfiguration(); // 实例化bean流程 beanFactory.preInstantiateSingletons(); }
DefaultListableBeanFactory:
@Override public void preInstantiateSingletons() throws BeansException { if (this.logger.isDebugEnabled()) { this.logger.debug("Pre-instantiating singletons in " + this); } List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames); // 触发所有的非懒加载的singleton beans 的初始化操作 for (String beanName : beanNames) { // 合并父 Bean 中的配置,注意 <bean id="" parent="" /> 中的 parent, // 后面会有文章专门讲解 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); // 非抽象、非懒加载的 singletons单例。 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { // 处理 FactoryBean,注意FactoryBean和BeanFactory的区别,后面单独 // 写文章讲解 if (isFactoryBean(beanName)) { // FactoryBean 的话,在 beanName 前面加上 ‘&’ 符号,然后再调用 getBean, // getBean方法最核心方法了会实例化bean,因为前面加上了‘&’符号,所以 // 获取的就是FactoryBean类型的对象了。 // -------------------------------------------------- // 这里简单普及下你定义一个类实现了FactoryBean中的getObject方法,getBean的时候 // 如果名字前加‘&’会获取这个对象本身,比如Demo类实现了FactoryBean,然后你 // getBean("&demo"),获取的就是Demo本身。 // -------------------------------------------------- // 所以源码中的这个getBean会把你实现了FactoryBean // 的类实例化,并放到spring容器中。 // 后续当你在程序中调用getBean(‘demo’),名字中不加的时候‘&’符号,进而 // 就会发现容器中已经存在了你的实例对象了(比如上面例子中的Demo), // 因为这次你没有加“&”符号,流程会有所不同,它会调用demo实例的getObject方法。 // 当然这里只是把实现了FactoryBean的类实例化,并放入容器了 final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName); ... } else { // 对于普通的 Bean,只要调用 getBean(beanName) 这个方法就可以进行初始化了 getBean(beanName); } } } // 到这里说明所有的非懒加载的 singleton beans 已经完成了初始化 // 如果我们定义的 bean 是实现了 SmartInitializingSingleton 接口的,那么在这里得到回调,忽略 for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { smartSingleton.afterSingletonsInstantiated(); return null; } }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } }
接下来分析getBean,会调用doGetBean方法,分析它:
protected <T> T doGetBean( String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { String beanName = transformedBeanName(name); Object bean; // 检查对象是否已经实例化过了,如果实例化过了,直接从缓存取出来。 // 如果没有注册过,这里返回肯定就是null了。里面的涉及到三级缓存(很多文章都这样叫)。 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是否实现了FactoryBean,如果是就调用它的getObject方法, // 如果不是就直接返回实例。 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { .... try { RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // 检查当前bean是否有depends-on相关的配置,如果有就先实例化依赖项。 // 对应的注解@DependsOn 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); } } } // 创建单例对象,主要逻辑. if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { // 执行具体实例化操作 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); } // 如果不是单例,创建非单例对象 else 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 { ...省去不重要代码 } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } // 如果传入了requiredType,检查requiredType和bean类型是否匹配,它也会尝试转换一下, // finishBeanFactoryInitialization方法的最开始有提到conversionService,就是 // 在这里会尝试做转换,这块平时工作用的也比较多,比如日期格式转换相关的,就是在这里 // 转换的。 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方法,它会执行具体的实例化,并把实例化后的对象放到容器中。
@Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isTraceEnabled()) { logger.trace("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; // 确保 BeanDefinition 中的 Class 被加载 Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // 准备方法覆盖,不重要 try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // 提供BeanPostProcessors接口一个机会来替换当前bean,来返回你自己定义的代理 // bean。 // 对应的方法postProcessBeforeInstantiation和postProcessAfterInstantiation. // 方法入参是bean,返回的也是bean,给你机会让你在方法中替换下。 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } try { // 创建实例的核心方法 Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { // A previously detected exception with proper bean creation context already, // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry. throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } }
AbstractAutowireCapableBeanFactory:
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) { // 实例化对象 instanceWrapper = createBeanInstance(beanName, mbd, args); } Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } ..... // 解决循环依赖问题的 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 { // 处理依赖注入比如@Autowaried,@Resource,实例对象的属性赋值操作。 populateBean(beanName, mbd, instanceWrapper); // 调用各种回调函数。比如BeanPostProcessor接口的回调, // InitializingBean接口的afterPropertiesSet的回调接口,以及各种 // Aware接口。 exposedObject = initializeBean(beanName, exposedObject, mbd); } .... return exposedObject; }
这里省去了不必要的代码。
分析到这里大体的情况已经比较清晰了,如果有兴趣可以再深入分析。
这里把initializeBean方法分析下,因为工作中用的比较多。
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { // 调用各Aware子类的接口 invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // 调用BeanPostProcessors接口的postProcessBeforeInitialization方法 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // 调用InitializingBean接口的afterPropertiesSet方法,各种框架种经常 // 用来,做一些启动后的初始化工作。 invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { // 调用BeanPostProcessors接口的postProcessAfterInitialization方法 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
总结
把整体的流程串了一遍,里面也有比较详细的注释。这里面涉及到很多spring给开发者留的口,来让开发者进行扩展回调使用,这些扩展口也是很有用。