所有的代码,都只保留了主干流程,为了阅读方便进行了简化处理,具体以源码为准
这里仅供参考
org.springframework.beans.factory.support.AbstractBeanFactory
类图
单例整体流程
// 通过工厂类,获取对象都是通过这个方法获取的
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
// 删除了不相干的代理,只保留主干
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
// Eagerly check singleton cache for manually registered singletons.
// 第一次检查, 从缓存里面取,如果已经存在直接返回, 这里可以
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null) {
return;
}
// Create bean instance. 创建单例
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName,
// 使用工厂方法的好处
// 1, 解偶,创建和使用解偶,使用的地方不需要知道具体的细节
// 2, 可以根据需要再生成对象,懒生成,而不是每次都生成对象,加快spring启动的速度
new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
// 具体创建单例的地方,这例使用就是下面讲解的AbstractAutowireCapableBeanFactory类
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);
}
return (T) bean;
}
// 整体的流程控制,保证单例的特性,防止重复生成对象
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "'beanName' must not be null");
// 加锁,二次检查
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!)");
}
// 这个地方很重要,保证了单例的特性,防止重复创建对象
beforeSingletonCreation(beanName);
// 创建对象
singletonObject = singletonFactory.getObject();
// 缓存对象
addSingleton(beanName, singletonObject);
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}
// 判断一个单例是否在创建中
public boolean isSingletonCurrentlyInCreation(String beanName) {
return this.singletonsCurrentlyInCreation.contains(beanName);
}
// 把单例对象的名称,加入到singletonsCurrentlyInCreation, 同步map]中
// 1, 为了后续的判断是否正在创建单例,
// 2, 防止重复创建对象,破换单例的特性
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
创建单例的细节
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory. doCreateBean
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) {
// 根据构造函数创建对象,如果构造函数有参数,会进行参数的解析,填充
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 {
// mbd合并
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 单利创建的时候,会先把beanName添加到一个map里面,+ lock,保证单例的特性
// 只要是单例 所以这里返回true: isSingletonCurrentlyInCreation(beanName)
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
// 为了解决循环依赖,单例对象第一次创建完成,会提前发布出去,
// 使用factory原因的可以进行延迟 生成代理对象
// 因为循环依赖属于小概率事件,所以注册一个factory,当真的存在循环依赖的时候
// 再生成真正的对象(spring AOP机制会在这里生成代理对象比较耗时),个人理解所以懒处理的形式,加快速度
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
// Srping AOP在这里进行增强,提前生成代理对象
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 填充参数, @Resource, @Autowired 都是在这里进行处理
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
// 初始化对象
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
// 如果提前发布了对象
if (earlySingletonExposure) {
// 如果提前发布了对象,但是进行了Spring AOP增强,生成了新的对象,这里需要获取最新的对象,
// 注意这里的参数是false,不能生成新的对象,只能从缓存里面取
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
// 体会为最新生成的对象比如 spring AOP代理对象,保证其单例特性,
// 如果这里不进行处理会导致循环依赖的对象和当前的对象不一致,破换了单例的特性
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}```
## Spring AOP如何解决,循环依赖的问题,同时保证单例特性
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator
类是AOP增强的主流程入口
```bash
// spring 解决单例循环依赖的时候,会提前注册一个BeanFactory,这里会提前生成代理类
@Override
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 写入这个map的原因,是为了保证单例,这里提前生成了代理类(因为循环依赖),
// A->B->A , 这种情况下,在创建B的时候,会调用这里提前生成A的代理类,
// 这个时候B里面的对A的引用已经是新的代理类了,但是A本身的还在初始化的过程中还没完成
// 需要完成A的初始化,但是还不能重新生成新的代理类否则就不是单例了,所以这里记录
// 在postProcessAfterInitialization的时候,对比引用,如果一样,就不重新生成代理类了
// 同时这个方法只会被调用一次,因为单例对象生成过成中会加锁,而且进行缓存,保证创建完成之后
// 只会从缓存里面取。同时最终A初始化完成之后,会把最终返回的引用对象体会为这里生成的代理对象,保证单例
this.earlyProxyReferences.put(cacheKey, bean);
// 生成代理类的具体实现
return wrapIfNecessary(bean, beanName, cacheKey);
}
// 正常的非循环依赖的对象,都从这里进行AOP的增强
// 这里的循环依赖指的是单例循环依赖(非构造函数依赖)
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 1, 如果是循环依赖则remove返回的bean ,和 当前是bean地址一样,这里是false,直接结束
// 2, 非循环依赖,那这里remove返回的是null,而bean不为空是先决条件,所以这里返回 true,进行类的增强,生成代理类
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 生成代理类的具体实现
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}