前言
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文件,按照里面的节点信息比如“”,实例化对应的对象,对象信息就是节点定义的信息,最后放入到map集合中,叫做“_容器”。_
后续“context.getBean(demoService.class)”方法其实就是从容器(前面的map集合)中获取到的实例。
这里的map集合其实就是spring容器,对应spring中FactoryBean这个类,看名字就知道它是管理bean的一个类。
看一下FactoryBean的部分源码:
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;
...
}
关注公众号:麒麟改bug,分享一份170多页的spring核心学习笔记。
可以看到它是一个接口,里面定义了获取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="" class="" 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;
}
关注公众号:麒麟改bug,分享一份170多页的spring核心学习笔记。
接下来再看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给开发者留的口,来让开发者进行扩展回调使用。这些扩展口也是很有用,限于篇幅,我后面会再写一篇文章把这些重要的扩展点配合源码给大家讲明白。
接下来还会跟大家分析springboot,springcloud,mybatis, springAOP等源码分析,spring是基础一定要先看懂这篇文章,可以自己对照着代码,自己跟一遍,这块懂了,后续的分析就都简单了。
喜欢文章记得关注我点赞哟,感谢支持!重要的事情说三遍,转发+转发+转发,一定要记得转发哦!!!