一、流程图
getBean()流程图:
其它分析图:
二、一些属性记录
scope="singleton" 单例 在启动(容器初始化之前), 就已经创建了bean,且整个应用只有一个。
scope="prototype" 多例 在用到对象的时候,才创建对象。
lazy-init="false" 默认为false, 不延迟创建,即在启动时候就创建对象
lazy-init="true" 延迟初始化, 在用到对象的时候才创建对象(只对单例有效)
init-method="init_user" 【对应对象的init_user方法,在bean创建时最后执行的初始化 】
destroy-method="destroy_user" 【在调用容器对象的destriy方法时执行 】
三、源码分析
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Terminal terminal = (Terminal) applicationContext.getBean("terminal");
个人总结
getBean() --> doGetBean() --> getSingleBean() --> createBean() --> doCreateBean() --> createBeanInstance()、populateBean()、initializeBean()
1、获取bean对象。getBean() --> doGetBean() --> getSingleBean() 。
getSingleBean()尝试从spring容器的三级缓存中获取单例bean对象,若没有获取到调用createBean(),createBean()调用了doCreateBean() 来创建bean对象。
2、创建bean对象。 createBean() --> doCreateBean() --> createBeanInstance()、populateBean()、initializeBean() 。
doCreateBean()方法内主要执行了createBeanInstance()、populateBean()、initializeBean()3个方法来进行bean实例的创建、属性依赖注入、bean初始化来完成一个spring完整bean对象的创建。
2.1 createBeanInstance():创建bean实例。使用合适的实例化策略来创建新的实例:工厂方法、构造函数自动注入、简单初始化。
2.2 populateBean():注入依赖的bean。为bean实例set属性值(Autowird的bean),为bean实例注入属性bean对象。
2.3 initializeBean():初始化bean。spring容器对这个bean对象进行一些初始化操作,init-method方法的执行。
下面的源码省略很多,只关注了大概的代码执行流程。
doGetBean()
getBean()方法调用的doGetBean()方法:
//AbstractBeanFactory
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
String beanName = this.transformedBeanName(name);
//从spring容器中获取bean
Object sharedInstance = this.getSingleton(beanName);
Object bean;
if (sharedInstance != null && args == null) {
...
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
/**
* 如果bean没有获取到,即bean尚未创建
*/
if (this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = this.getParentBeanFactory();
// 如果当前BeanFactory不需要创建实例的BeanDefinition,则委托父级bean工厂获取bean对象
if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
String nameToLookup = this.originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
}
if (args != null) {
return parentBeanFactory.getBean(nameToLookup, args);
}
if (requiredType != null) {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
return parentBeanFactory.getBean(nameToLookup);
}
...
//如果是单例
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);//创建bean
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
//如果对象是FactoryBean类型,进行相应处理
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
//如果是多例
var11 = null;
Object prototypeInstance;
try {
this.beforePrototypeCreation(beanName);
//创建bean
prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
//如果对象是FactoryBean类型,进行相应处理
bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
//其它scope类型处理
...
}
return bean;
}
getSingleton()
Spring 三级缓存
1. singletonObjects:这是Spring容器中单例 Bean 的缓存,它保存了已经完全初始化的单例 Bean 的实例。在这个缓存中,Bean 的名字作为键,Bean 的实例作为值。
2. earlySingletonObjects:这个缓存包含了尚未完成构造的单例 Bean 的半成品(即尚未执行完构造函数的 Bean 实例)。这些 Bean 是不完整的,但已经创建,用于解决单例bean的循环依赖问题。
3. singletonFactories:这个缓存用于存储用于创建单例 Bean 的工厂对象ObjectFactory。这些工厂对象是 Bean 实例化的原始来源。
从spring容器中获取bean的方法getSingleton():
//DefaultSingletonBeanRegistry
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从单例bean的容器Map获取
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
synchronized(this.singletonObjects) {
//预加载的Map容器获取
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {//2个容器Map都没有获取到
//获取bean的ObjectFactory对象工厂
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//对象工厂不为空,从对象工厂获取bean对象(注意这里是getObject()获取bean,没有去create)
singletonObject = singletonFactory.getObject();
//放入预加载的容器Map中
this.earlySingletonObjects.put(beanName, singletonObject);
//移除bean的ObjectFactory,因为bean已加入预加载的容器Map中,不再需要ObjectFactory
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
1.从springIOC单例容器获取bean
2.没有获取到,去spring预加载容器获取bean
3.没获取到,从ObjectFactory获取bean
4.都没有获取到,return null
从三级缓冲理解:
1. 当容器需要获取某个Bean时,它会首先查找singletonObjects缓存,如果找到就直接返回Bean的实例。
2. 如果没有找到,容器会检查earlySingletonObjects缓存,如果存在半成品Bean,就将其返回。
3. 如果仍然没有, 则使用工厂对象ObjectFactory的 getObject() 方法来创建单例对象。放到 earlySingletonObjects 中返回。
doCreateBean()
再看没有获取到bean去执行的createBean()方法,createBean()方法去调用了doCreateBean(),doCreateBean()是spring创建bean对象的核心方法:
// AbstractAutowireCapableBeanFactory
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
...
if (instanceWrapper == null) {
//1.创建bean实例(使用合适的实例化策略来创建新的实例:工厂方法、构造函数自动注入、简单初始化)
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
...
//循环依赖条件检查:单例 且 允许循环依赖属性为true(默认true) 且 当前bean处于创建中状态
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
...
// 满足循环依赖条件,将创建实例的ObjectFactory加入工厂Map中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
...
// 2.依赖注入,即 setXX(@Autowird的bean)
this.populateBean(beanName, mbd, instanceWrapper);
// 3.spring对这个bean对象进行一些初始化操作:applyBeanPostProcessorsBeforeInitialization(初始化前置回调)、invokeInitMethods(初始化方法)、applyBeanPostProcessorsAfterInitialization(初始化后置回调)。init-method方法的执行。
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
...
/**
* 循环依赖的处理
*/
//若有循环依赖会去从工厂Map获取ObjectFactory,从ObjectFactory获取bean(这时的bean就是前面1创建的bean实例,
if (earlySingletonExposure) {
Object earlySingletonReference = this.getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
String[] dependentBeans = this.getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
String[] var12 = dependentBeans;
int var13 = dependentBeans.length;
for(int var14 = 0; var14 < var13; ++var14) {
String dependentBean = var12[var14];
if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
}
}
}
}
doCreateBean()分析
1.createBeanInstance():创建bean实例(使用合适的实例化策略来创建新的实例:工厂方法、构造函数自动注入、简单初始化)。
1.2 若满足循环依赖条件,将创建bean实例的ObjectFactory加入FactoryMap工厂容器中。(循环依赖条件:单例 且 允许循环依赖属性为true(默认true) 且 当前bean处于创建中状态)
2.populateBean():依赖注入,即 setXX(@Autowird的bean),为bean实例设置属性。
3.initializeBean():spring对这个bean对象进行一些初始化操作:applyBeanPostProcessorsBeforeInitialization(初始化前置回调)、invokeInitMethods(初始化方法)、applyBeanPostProcessorsAfterInitialization(初始化后置回调)。init-method方法的执行。
4.循环依赖的处理。若有循环依赖会去从FactoryMap获取ObjectFactory(1.2put()的),从ObjectFactory获取bean(这时的bean就是前面1创建的bean实例。注意:spring 虽支持了bean的循环依赖,但是循环依赖依然属于设计上的问题,应当尽量避免!
createBeanInstance()
// AbstractAutowireCapableBeanFactory
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 检查确认bean是可实例化的
Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
} else {
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return this.obtainFromSupplier(instanceSupplier, beanName);
} else if (mbd.getFactoryMethodName() != null) {
// 使用工厂方法实例化bean对象(Class+反射生成bean)
return this.instantiateUsingFactoryMethod(beanName, mbd, args);
} else {
//无工厂方法
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
Object var8 = mbd.constructorArgumentLock;
synchronized(mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
// 配置了自动装配属性 使用容器的自动装配实例化 否则使用默认无参构造方法实例化
return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
} else {
// 使用bean的构造方法进行实例化 默认使用无参构造方法 如果配置了容器自动装配 则调用匹配的构造方法实例化
Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
return ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args) ? this.instantiateBean(beanName, mbd) : this.autowireConstructor(beanName, mbd, ctors, args);
}
}
}
}
addSingletonFactory()
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized(this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
//将beanName、bean的ObjectFactory放入Map中
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}