不知道各位还记不记得 Spring 对 bean 生命周期的管理方式:Spring 默认采用单例的方式管理 Bean,在获取 Bean 实例的时候会经过一个缓存进行获取,若是还未初始化,那么就会先将 Bean Definition 进行一个初始化放入缓存,而后再经过缓存获取。java
那么在上一章中,我也在总结中提到过:在执行完 beanDefinitionReader.loadBeanDefinitions(resource);
这段代码以后,仅仅是完成了 beanDefinition 的解析与注册,还未到初始化阶段。缓存
在这一章中,我将详细对 bean 在什么时候进行实例化、如何放入缓存这部分的内容进行详细的分析。并发
首先是方法入口,也就是咱们获取 bean 实例的代码:app
Student student = defaultListableBeanFactory.getBean("student", Student.class);
复制代码
咱们深刻到 getBean() 这个方法中:ide
AbstractBeanFactory.getBean()post
能够发现,这里调用的是 AbstractBeanFactory 的 getBean() 方法,它是 DefaultListableBeanFactory 的父类。ui
这里分别 getBean() 方法进行了不一样的重载,而且底层是调用了 doGetBean() 这个方法:this
//---------------------------------------------------------------------
// Implementation of BeanFactory interface
//---------------------------------------------------------------------
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
@Override
public Object getBean(String name, Object... args) throws BeansException {
return doGetBean(name, null, args, false);
}
复制代码
继续深刻到 doGetBean() :spa
AbstractBeanFactory.doGetBean()prototype
这个方法的代码很是的多,咱们当下先关注从缓存获取 bean 实例的逻辑,所以我先省略掉后续的代码:
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 获取到bean的惟一标识
final String beanName = transformedBeanName(name);
Object bean;
// 提前地去检查缓存中是否存在相应的bean实例
// 若是存在就返回相应的单例bean
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
//....
}
复制代码
能够发现上面这个方法会从单例缓存池中获取单例bean实例,因而咱们能够接着深刻:
@Override
@Nullable
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
复制代码
深刻到重载的 getgetSingleton() 方法
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 经过单例bean缓存 singletonObjects 获取到对应的实例
// 这里的容器依然是经过 ConcurrentHashMap 来实现的
// key=惟一标识、value=单例bean实例
Object singletonObject = this.singletonObjects.get(beanName);
// 若是发现缓存中不存在对应的bean实例, 而且发现这个bean正处于建立过程当中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 那么就会进行一个同步
// 避免并发环境下出现的读写不一致的问题
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
复制代码
咱们回到 doGetBean() ,看看后续会进行什么逻辑:
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
// 若是缓存池中存在相应的实例, 在这里就会直接进行返回
// 没有的话就会返回一个空值
Object sharedInstance = getSingleton(beanName);
// 若是成功从单例缓存池中获取到了实例
if (sharedInstance != null && args == null) {
// 紧接着去打印一下日志
if (logger.isTraceEnabled()) {
//....
}
// 将缓存中获取到的Object转换为bean实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
// 这里就是缓存池中不存在实例的逻辑了
else {
// 判断是不是prototype这种类型的bean正在被建立
// 若是是, 直接抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 下面这块逻辑就是检查 BeanDefinition 是否在工厂中存在
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
//....
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
// 获取到 BeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 检查 bean 的依赖关系
// 好比 A 依赖于 B, 那么就须要先把 B 建立出来
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
//....
}
// 真正建立 bean 实例的逻辑
if (mbd.isSingleton()) { // 判断scope是不是singleton
// 这里经过了 lambda 表达式来处理方法的执行
// 首先会建立一个bean实例, 而后 getSingleton() 方法又会将建立好的 bean 实例缓存到单例缓存池
sharedInstance = getSingleton(beanName, () -> {
try {
// 这里就会进行一个 bean 实例的建立流程
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 判断scope是不是prototype
else if (mbd.isPrototype()) {
// ....省略
}
else { // 这边就是其余scope类型的bean实例化的逻辑
// ....省略
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// ...省略
return (T) bean;
}
复制代码
经过上述代码,咱们可以明确,这个方法中包含了 "建立 bean 实例"、"将实例缓存到单例缓存池中" 这两个逻辑。
咱们先假设已经成功建立出 bean 实例了,先去看看把实例放入缓存池的代码 —— getSingleton():
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// ... 省略逻辑咱们不须要太关心, 就是一些前置、后置处理
// 这里就会获取到单例bean的对象
// 也就是经过lambda表达式中方法的返回值中获取到单例bean实例
try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
// 关键是这里, 会将惟一标识、单例bean对象放入到缓存中
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
// 最后把这个单例bean实例给返回
return singletonObject;
}
}
复制代码
咱们深刻一下单例 bean 建立实例,也就是lambda表达式中的代码:java createBean(beanName, mbd, args);
的执行过程:
AbstractAutowireCapableBeanFactory.createBean()
AbstractAutowireCapableBeanFactory 这个类一样是 DefaultListableBeanFactory 的父类:
/** * Central method of this class: creates a bean instance, * populates the bean instance, applies post-processors, etc. * @see #doCreateBean */
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
// ... 省略掉其余的逻辑, 只关心建立实例的逻辑
try {
// 这里又调用了一个 doCreateBean() 方法
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);
}
}
复制代码
咱们继续深刻到 doCreateBean() 内部的逻辑:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException {
// ... 省略掉一些代码
if (instanceWrapper == null) {
// 这里就是bean真正建立的方法
// 传入惟一标识、BeanDefinition、参数
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// ... 省略掉一些代码
return exposedObject;
}
复制代码
继续深刻到 createBeanInstance()
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 省略掉其他代码
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 经过惟一标识、bean定义去实例化bean
return instantiateBean(beanName, mbd);
}
}
// 省略掉其他代码
}
复制代码
继续深刻到 instantiateBean()
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
//...
else {
// 注意这里的 instantiate 方法, 继续跟进
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
//...
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
复制代码
继续深刻 instantiate()
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {
// 获取到构造方法对象
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 经过 BeanUtils.instantiateClass() 进行实例化
// 经过反射的方式进行一个实例化
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
复制代码
经过这篇文章的分析,咱们必需要明确如下几个关键点:
就哪怕我分析的代码一点都没看懂也不要紧,这几个点是必需要明确的。
那么下一篇,将带来 Spring Bean 建立策略的一个详细分析。