1. 实例化sping容器
具体的有三种实现方式
ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:***");
ApplicationContext ac = new AnnotationConfigApplicationContext(***.class);
ApplicationContext ac = new FileSystemXmlApplicationContext("***");
如果我们使用的是上诉第二种实例化spring容器的方式则会先在spring容器中对该配置类进行注册,在通过配置类去进行扫描
2. 如果是xml则是在obtainFreshBeanFactory方法生成beanFactory对象,生成BeanDefinition对象,并装载进入beanDefinitionMap中
工厂类为DefaultListableBeanFactory
3. 扫描符合springbean规则的class集合并将这些class其封装成beanDefinition对象置入beanDefinitionMap中
//使用的是refresh()方法下的该方法
//beanFactory中有一个属性beanDefinitionMap
//调用有点繁复,各位可以自行debug窥探一二
invokeBeanFactoryPostProcessors(beanFactory);
beanDefinitionMap的组成为<类名,beanDefinition>
3、遍历beanDefinitionMap并对其beanDefinition进行验证
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
//获取beanDefinitionMap中beanName集合
List beanNames = new ArrayList(this.beanDefinitionNames);
//遍历
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
final FactoryBean> factory = (FactoryBean>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction() {
@Override
public Boolean run() {
return ((SmartFactoryBean>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
//调用getBean
getBean(beanName);
}
}
}
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
4.做一些先驱操作,如dependsOn
protected T doGetBean(
final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
//后续循环依赖会用上
//先去单例池中找
//没有查看是否是处于创建状态中
//详见代码块..
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
...
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
String[] dependsOn = mbd.getDependsOn();
//检测是否有dependsOn依赖,有的话先加载
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);
}
}
}
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory
通过以上流程步骤进入到创建单例bean的过程creatBean();
-
public Object getSingleton()
public Object getSingleton(String beanName, ObjectFactory> singletonFactory) {
Assert.notNull(beanName, "'beanName' must not be null");
Map var3 = this.singletonObjects;
//上锁
synchronized(this.singletonObjects) {
//去单例缓存池里尝试获取该对象,若能获取到,则无须创建,返回即可
Object singletonObject = this.singletonObjects.get(beanName);
//需要创建
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (this.logger.isDebugEnabled()) {
this.logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
/*
* 将 beanName 添加到 singletonsCurrentlyInCreation 集合中,
* 用于表明 beanName 对应的 bean 正在创建中
* 可以解决循环依赖问题
*/
this.beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = this.suppressedExceptions == null;
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet();
}
try {
// 通过 getObject 方法调用 createBean 方法创建 bean 实例
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
throw ex;
} finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 将 beanName 从 singletonsCurrentlyInCreation 移除
this.afterSingletonCreation(beanName);
}
//如果创建成功
if (newSingleton) {
/*
* 将 键值对添加到 singletonObjects 集合中,
* 并从其他集合(比如 earlySingletonObjects)中移除 singletonObject 记录
*/
this.addSingleton(beanName, singletonObject);
}
}
return singletonObject != NULL_OBJECT ? singletonObject : null;
}
}
步骤
1.先从 singletonObjects 集合获取 bean 实例,若不为空,则直接返回
2.若为空,进入创建 bean 实例阶段。先将 beanName 添加到 singletonsCurrentlyInCreation
3.通过 getObject 方法调用 createBean 方法创建 bean 实例
4.将 beanName 从 singletonsCurrentlyInCreation 集合中移除
5.将映射缓存到 singletonObjects 集合中
5. 创建bean
-
createBean()
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 解析 bean 的类型
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 {
// 在 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);
}
// 调用 doCreateBean 创建 bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
- doCreateBean()真正的创建bean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//实例化
//反射创建对象,这里是被包裹住了
//注意这里创建的是java 对象,不是bean,且此时里面没有属性
//见下面代码
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// Allow post-processors to modify the merged bean definition.
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;
}
}
/*
* earlySingletonExposure 是一个重要的变量,这里要说明一下。该变量用于表示是否提前暴露
* 单例 bean,用于解决循环依赖。earlySingletonExposure 由三个条件综合而成,如下:
* 条件1:mbd.isSingleton() - 表示 bean 是否是单例类型
* 条件2:allowCircularReferences - 是否允许循环依赖
* 条件3:isSingletonCurrentlyInCreation(beanName) - 当前 bean 是否处于创建的状态中
*
* earlySingletonExposure = 条件1 && 条件2 && 条件3
* = 单例 && 是否允许循环依赖 && 是否存于创建状态中。
*是否允许循环依赖,允许则暴露一个工厂
*/
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory
6. createBeanInstance() 推断构造方法并使用该构造方法构建对象
//推断构造方法
Constructor>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//构建对象
return autowireConstructor(beanName, mbd, ctors, args);
}
7. bean初始化
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction
二、讲一讲细节
循环依赖
问题:
假如有两个类A,B循环依赖
根据bean的生命周期,在创建A的bean时,扫描到A时实例化一个A实例,然后填充属性,此时发现有没有属性B的bean于是去创建B的bean,同理,创建B时也会产生同样的问题,这就是循环依赖问题
那么spring是如何解决这个问题的呢?
答案是singletonsCurrentlyInCreation集合和spring三级缓存
1.singletonsCurrentlyInCreation集合
以下为顺序调用:
- (1) 在doGetBean()方法下一开始就查看是否有该bean
Object sharedInstance = getSingleton(beanName);
->
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//一开始在singletonObjects搜寻
Object singletonObject = this.singletonObjects.get(beanName);
//没找到则在singletonsCurrentlyInCreation集合中搜寻
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
//在earlySingletonObjects Map中搜寻
//一级缓存
singletonObject = this.earlySingletonObjects.get(beanName);
//还没有的情况下
if (singletonObject == null && allowEarlyReference) {
//生产工厂去生产一个该bean
ObjectFactory> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//二级缓存
singletonObject = singletonFactory.getObject();
//存入earlySingletonObjects Map
//三级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
//将该该类从工厂中删除
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
- (2)在doGetBean()方法下调用的getSingleton(String beanName, ObjectFactory> singletonFactory)下有一个:
beforeSingletonCreation(beanName)方法:
this.singletonsCurrentlyInCreation.add(beanName)
将该对象的名称加入singletonsCurrentlyInCreation集合
这两个层面的内容应该很容易看懂,(1)执行在(2)前,所以在循环创建的过程中,第二次创建就能进入getSingleton()直接进行bean创建
(3)三级缓存
一级缓存 singletonObjects Map
创建bean成功就会进入一级缓存二级缓存 singletonFactory Map
三级缓存 earlySingletonObjects
如果支持循环依赖才会有三级缓存
循环依赖具体由allowCircularReferences属性来决定,若支持,则直接在二级缓存中创建该工厂
protected void addSingletonFactory(String beanName, ObjectFactory> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
为什么会有三级缓存呢?按照道理而言只需要有二级缓存生产对象就可以了啊?
答:因为工厂生产对象需要花费时间,而我们只需要工厂生产完成以后将对象放入三级缓存,后续再需要直接从二级缓存中拿就可以了。