【笔记--spring创建单例bean的流程】

spring创建单例bean的流程

  • 简单跟踪一下源码

spring 创建bean会经过三个过程。一是实例化(Instantiation),二是依赖注入,三是初始化(Initialization)。
实例化:就是使用构造函数new出一个对象,。
初始化:调用实现的aware相关接口,调用PostBeanProcessor相关方法,调用initMethod。

简单跟踪一下源码

新建两个简单的entity,以创建普通的单例bean为例子:
这两个实体都加了@component注解,那么当运行程序时,spring肯定会将这两个bean创建出来并加载进容器当中。

@Component
@Data
public class Cat {
    private Integer catAge = 2;
    @Resource
    private Dog dog;
}
@Component
@Data
public class Dog {
    private Integer dogAge = 3;
}

运行主程序,以AbstractApplicationContextrefresh方法为入口,首先看preInstantiateSingletons()。_这个方法主要做的是获取bean名称的集合,并迭代。位置是AbstractApplicationContext.refresh()=>AbstractApplicationContext.finishBeanFactoryInitialization()=>DefaultListableBeanFactory.preInstantiateSingletons()。
假设spring先创建Cat的bean,当bean名称迭代到cat时,就会执行this.getBean(beanName)

public void preInstantiateSingletons() throws BeansException {
        ...
        //获取bean名称集合
        List<String> beanNames = new ArrayList(this.beanDefinitionNames);
        Iterator var2 = beanNames.iterator();
        while(true) {
            String beanName;
            Object bean;
            do {
	            while(true) {
		            ...
		            //省略的部分是一些判断,不关注
		            //当创建Cat的bean的时候会执行这个方法
		            this.getBean(beanName);
	            }
            } while(!(bean instanceof FactoryBean));
            ...
        }
    }

getBean方法跳转到AbstractBeanFactory.doGetBean()

protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
	String beanName = this.transformedBeanName(name);
    Object sharedInstance = this.getSingleton(beanName);
    Object beanInstance;
    if (sharedInstance != null && args == null){...}else{
    	...
    	try{
    		...
    		String[] dependsOn = mbd.getDependsOn();
            String[] var12;
            //如果类上加了@DependsOn的注解,就会执行里面的代码,这里先不关注
    		if (dependsOn != null) {...}
    		//根据bean的类型,执行对应的逻辑创建bean
    		if (mbd.isSingleton()) {
    		//创建单例bean
    			sharedInstance = this.getSingleton(beanName, () -> {
    				//执行完这个lambda之后,返回一个bean到 getSingleton()里
    				//接着 getSingleton() 会把这个bean注册进容器中
                    try {
                        return this.createBean(beanName, mbd, args);
                    } catch (BeansException var5) {
                        this.destroySingleton(beanName);
                        throw var5;
                    }
                });
                beanInstance = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    		}else if(...)...
    	}
    }

AbstractAutowireCapableBeanFactory.createBean()_ – 创建bean正式进入流程。createBean()_按顺序主要做了以下工作:

  1. 进行bean实例化前的工作 –applyBeanPostProcessorsBeforeInstantiation(),如果这个方法已经返回了一个不为null的bean,那spring就不用做doCreateBean()_这步操作去实例化bean了,并且立马进行初始化后的工作 – applyBeanPostProcessorsAfterInitialization()。(实例化前后的工作可以使用InstantiationAwareBeanPostProcessor接口自定义)
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
	...
	Object beanInstance;
    try {
    	//实例化前工作
        beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
        if (beanInstance != null) {
        	//不为null就直接返回到上一级方法(getSingleton())
            return beanInstance;
        }
    } catch (Throwable var10) {
        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var10);
    }
    try {
        beanInstance = this.doCreateBean(beanName, mbdToUse, args);
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Finished creating instance of bean '" + beanName + "'");
        }
        return beanInstance;
    } catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
        throw var7;
    } catch (Throwable var8) {
        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8);
    }
    ...
}
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {	//先看需不需要
    	//再看有没有
        if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {	
            Class<?> targetType = this.determineTargetType(beanName, mbd);
            if (targetType != null) {
            	//执行 实例化前
                bean = this.applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                if (bean != null) {
                	//执行 初始化后
                    bean = this.applyBeanPostProcessorsAfterInitialization(bean, beanName);
                }
            }
        }
        mbd.beforeInstantiationResolved = bean != null;
    }
    return bean;
}
  1. 如果完成了实例化前的工作同时返回的是null,则doCreateBean()_去实例化和初始化bean。
  2. this.createBeanInstance(beanName, mbd, args)_创建bean实例
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
    	//如果是单例,甭管有没有就先从缓存中移除
        instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
   		//创建
        instanceWrapper = this.createBeanInstance(beanName, mbd, args);
    }
    ...
    ...
    try {
    	//填充属性
        this.populateBean(beanName, mbd, instanceWrapper);
        //初始化
        exposedObject = this.initializeBean(beanName, exposedObject, mbd);
    } catch (Throwable var18) {
        if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
            throw (BeanCreationException)var18;
        }
        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
    }
    ...
}
  1. this.populateBean()首先进行bean实例化后的工作,如果spring做完这些工作之后并返回了false,就会退出populateBean()。也就是说,之后注入依赖的代码就不会执行了,直接到步骤6进行初始化了。
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
	if (bw == null) {
        if (mbd.hasPropertyValues()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
        }
    } else {
    	if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
            //获取 bean实例化后置处理器 集合
            //迭代,逐一执行每个处理器的 实例化后 的工作
            Iterator var4 = this.getBeanPostProcessorCache().instantiationAware.iterator();
            while(var4.hasNext()) {
                InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var4.next();
                //执行 实例化后 的工作
                //如果返回了false,则直接退出方法
                if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                    return;
                }
            }
        }
        ...
        boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
        boolean needsDepCheck = mbd.getDependencyCheck() != 0;
        PropertyDescriptor[] filteredPds = null;
        if (hasInstAwareBpps) {
            if (pvs == null) {
                pvs = mbd.getPropertyValues();
            }
            PropertyValues pvsToUse;
            for(Iterator var9 = this.getBeanPostProcessorCache().instantiationAware.iterator(); var9.hasNext(); pvs = pvsToUse) {
                InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var9.next();
                //注入依赖
                //CommonAnnotationBeanPostProcessor.postProcessProperties()
                pvsToUse = bp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
                ...
            }
        }
        ...
    }
}
  1. 注入依赖。因为Cat需要注入Dog的依赖,所以这时候spring调用了getBean()_获取Dog的bean。因为现在假设Cat是在Dog之前创建的,所以这时候由于获取不到Dog的bean而去创建。
  2. Dog_bean实例化与初始化完成并返回后,Cat的依赖注入完成,就准备初始化了。this.initializeBean()。与实例化一样,依然需要进行初始化前和后的工作,这部分工作可以实现接口自定义。(初始化前后的工作可以直接或间接实现BeanPostProcessor接口自定义)
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged(() -> {
            this.invokeAwareMethods(beanName, bean);
            return null;
        }, this.getAccessControlContext());
    } else {
        this.invokeAwareMethods(beanName, bean);
    }
    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
    	//初始化前
        wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
    }
    try {
    	//初始化方法
        this.invokeInitMethods(beanName, wrappedBean, mbd);
    } catch (Throwable var6) {
        throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
    }

    if (mbd == null || !mbd.isSynthetic()) {
    	//初始化后
        wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
    return wrappedBean;
}
  1. 到目前为止bean的创建就结束了,createBean()方法结束, 把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) {
            ...
            this.beforeSingletonCreation(beanName);
            boolean newSingleton = false;
            try {
            	//执行createBean()
                singletonObject = singletonFactory.getObject();
                //createBean()结束,bean完成创建
                newSingleton = true;
            } catch (IllegalStateException var16) {
                ...
            } catch (BeanCreationException var17) {
                ...
            } finally {
                ...
            }
            if (newSingleton) {
            	//将bean注册到容器
                this.addSingleton(beanName, singletonObject);
            }
        }

        return singletonObject;
    }
}
//单例池
private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);

protected void addSingleton(String beanName, Object singletonObject) {
    synchronized(this.singletonObjects) {
    	//this.singletonObjects 就是用来存放单例bean的容器了,单例池,是一个map
    	//spring就是从这里获取单例bean的
        this.singletonObjects.put(beanName, singletonObject);
        this.singletonFactories.remove(beanName);
        this.earlySingletonObjects.remove(beanName);
        this.registeredSingletons.add(beanName);
    }
}

假设在cat之后,有一个bean需要创建,叫mouse,它依赖cat:

@Component
@Data
public class Mouse {
    @Resource
    private Cat cat;
}

当Mouse要注入Cat的依赖,调用了getBean(),因为Cat已经创建了,所以直接从单例池中获取。

protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
    String beanName = this.transformedBeanName(name);
    //从 singletonObjects 单例池 获取到了Cat的bean
    Object sharedInstance = this.getSingleton(beanName);
    Object beanInstance;
    if (sharedInstance != null && args == null) {
    	...
    	beanInstance = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
    }else{....}
    return this.adaptBeanInstance(name, beanInstance, requiredType);
}

你可能感兴趣的:(笔记,spring)