概述
spring在初始化时,容器会自动将创建去创建非懒加载的单例Bean,由于spring创建Bean的过程涉及到的步骤极其复杂,笔者本篇只是对创建Bean的流程进行概述,具体细节会在后续文章中给大家展示
Bean的实例化
public void preInstantiateSingletons() throws BeansException {
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
for (String beanName : beanNames) { // userService
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
// 根据beanName去创建bean
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((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
重温以下方法的调用栈:
refresh() --> finishBeanFactoryInitialization(beanFactory) --> preInstantiateSingletons()
在preInstantiateSingletons() 这个方法里面最主要的就是这两个循环了
第一个循环首先是对spring扫描到的BeanDefinition进行循环,对每个循环的BeanDefinition所代表的类进行判断,判断对应的类是不是单例,是不是非抽象,是不是非懒加载的Bean,如果全部满足才会进行创建Bean的操作,有关于FactoryBean的创建已经在笔者《spring之BeanFactory源码解析》一文中进行了说明,这里就不再过多说明
我们直接进入spring创建Bean的方法doGetBean
Object sharedInstance = getSingleton(beanName); // Map<>
首先依然是从单例池里面进行获取,如果获取到了就会直接返回
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
如果说单例池里面没有这个Bean还会去父BeanFactory里面去寻找,如果说父BeanFactory里面也没有,那么就需要去创建 这个Bean了
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
String[] dependsOn = mbd.getDependsOn();
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 {
// 先去生成所依赖的bean
getBean(dep); // getBean("xxx")
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
在这一段代码里面做了如下操作
- 合并BeanDefinition
2)获取当前创建的Bean所依赖的Bean,也就是注解@DependsOn的Bean,在创建当前Bean之前,会先对这些所依赖的Bean进行创建
在这里有一个比较重要的判断是 isDependent(beanName, dep) ,就是去判断循环依赖关系举个例子:
假如类A dependOn 类B,同时类B dependOn 类A,那么就会产生循环依赖关系,基于dependOn这个属性产生的循环依赖关系是没有办法进行解决的 ,所以如果有这种情况就会直接抛出异常,这一部分的实现是基于两个map来实现的,一个map存储,这个Bean依赖哪些Bean,而另外一个map存储我当前的Bean被哪些bean所依赖,根据这两个map来完成判断
接下来看看一个单例bean到底是如何进行创建的,创建单例Bean依赖 getSingleton 这个方法
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
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);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
singletonObject = singletonFactory.getObject(); // createBean()
newSingleton = true;
}
....
....
}
}
在这里最需要关注的是这个getObject()这个方法,singletonFactory是在方法内的第二个形参,传入的是一个表达式,这里调用的getObject其实就是执行表达式里面的createBean这个方法
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
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) {.....}
try {
Object bean = resolveBeforeInstantiation(beanName, mbdToUse); // 对象
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {...}
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {....}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
即然要实例化一个类,拿前提条件当然是拿到这个类的class对象了,这里不免会产生一个疑问,class对象难道不是扫描的时候进行加载的么?
答案是:不是的,spring在进行扫描的时候并不是通过class对象来获取类上的信息,而是通过ASM技术直接读取字节码文件获取到类的信息,然后封装到BeanDefinition中的,所以到此位置是没有进行类的加载的
Object bean = resolveBeforeInstantiation(beanName, mbdToUse)
在这个方法里就是进行一些实例化之前的操作,在这里就涉及到spring中的后置处理器了
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
在这里回去spring容器里面找 InstantiationAwareBeanPostProcessor 这个处理器,如果有这个类型的处理器就会执行其postProcessBeforeInstantiation 这个方法,如果这个方法返回出来的对象不是null,那么还会执行一个实例化之后的一些操作,对应postProcessAfterInitialization这个方法,然后就会在这里直接进行返回这个Bean,从而不会有后续对这个Bean的实例化操作
通过这里的这个机制,如果有一天,我们不想让spring给我们创建对象,而是想通过自己进行对象的创建,那么我们既可以实现InstantiationAwareBeanPostProcessor 这个后置处理器,然后将自己创建对象进行返回
在进行spring实例化之前的一些操作过后,对应的就是Bean的实例化了,调用 doCreateBean(beanName, mbdToUse, args);进行bean的实例化
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {...}
mbd.postProcessed = true;
}
}
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); // AService
}
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {....}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false); // earlySingletonObjects
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {...}
}
}
}
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {...}
return exposedObject;
}
在这个实例化的方法里面可以看到applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
这里也是一次后置处理器的调用,spring在这通过后置处理器向程序员提供了一个可以对BeanDefinition操纵的机会,因为虽然Bean已经被实例化出来了,但是也仅仅是被实例化出来了而已,对于后面的属性填充,生命周期方法以及aop操作依然收到BeanDefinition的影响
结束上述,就会进行填充属性populateBean(beanName, mbd, instanceWrapper);
然后进入initializeBean(),在这里面还会进行 Aware接口的调用,初始化前,初始化,初始化后这四步操作
首先来看Aware接口的调用这里会分别对实现了BeanNameAware,BeanClassLoaderAware,BeanFactoryAware
这三个接口进行属性填充,然后分别调用set/getXXX方法,但是我们知道在Spring中不仅仅只有着三个XXXAware
那么其他的Aware接口会在哪里执行呢???(下文揭晓答案)
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
而对于初始化前,初始化后这两步操作分别对应着一个后置处理器进行操作
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 4.2、初始化前
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 4.3、初始化
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 4.4、初始化后 AOP ()
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
前面提出了一个问题,spring中其他的Aware接口是在哪里执行的呢?答案就在初始化前的操作里面
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
这里通过getBeanPostProcessors()方法获取spring中所有的后置处理器,然后执行其postProcessBeforeInitialization()方法
除了我们自己加入的BeanPostProcessor,其中有一个BeanPostProcessor 叫做ApplicationContextAwareProcessor
在这个BeanPostProcessor的postProcessBeforeInitialization方法如下
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
return bean;
}
AccessControlContext acc = null;
...
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {invokeAwareInterfaces(bean);}
return bean;
}
在这个方法里面会判断传入的Bean是不是实现了这些接口中的某一个接口,如果是实现了的话就会回调其相应Aware接口的set方法
对于初始化操作,则是去判断是否实现了InitializingBean 然后回调其中的afterPropertiesSet
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
...
总结
关于spring中bean的生命周期贯穿着非常多的后置处理器,通过这些处理器完成对象的实例化,初始化,以及保证可扩展性
大体的流程如下
1)实例化前
2)实例化(其中包括构造方法的推断)
3)BeanDefinition的修改
4)属性填充
5)执行xxxAware
6)初始化前
7)初始化
8)初始化后
具体细节会在后续更新