Spring Bean初始化过程 本文讨论Spring容器下的Bean初始化过程。
创建SpringBoot项目,创建如下类,通过它研究Bean的初始化过程。
1 2 3 4 5 6 7 8 9 10 11 12 @Component public class Cat implements ApplicationContextAware { public Cat () { System.out.println("cat 被创建" ); } @Override public void setApplicationContext (ApplicationContext applicationContext) throws BeansException { System.out.println("aware" ); } }
直接将断点定位到org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
方法上,执行到这里容器已经将Bean全部解析出来,然后逐个初始化,我们直接查看初始化过程。
可以看出,他是遍历beanNames列表,逐个初始化,遍历有两个分支,下面的分支是调用getBean(beanName)
方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 @Override public void preInstantiateSingletons () throws BeansException { if (logger.isTraceEnabled()) { logger.trace("Pre-instantiating singletons in " + this ); } List<String> beanNames = new ArrayList <>(this .beanDefinitionNames); for (String beanName : beanNames) { 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; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } } else { 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(); } } } }
继续按照断点走,最后来到这里。这里要做的是,使用反射创建Bean,对Bean进行初始化。
详细解释看注释
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 protected Object doCreateBean (final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { BeanWrapper instanceWrapper = null ; instanceWrapper = createBeanInstance(beanName, mbd, args); final Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); exposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) { } return exposedObject; }
下面是初始化Bean的过程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 protected Object initializeBean (final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { invokeAwareMethods(beanName, bean); Object wrappedBean = bean; wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); invokeInitMethods(beanName, wrappedBean, mbd); wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); return wrappedBean; }
这样一个正常的Bean就创建完成了,这个Bean经历了
反射创建
依赖注入 (通过InstantiationAwareBeanPostProcessor实现的)
回掉各种Aware
回掉Init方法
具有循环依赖的Bean的创建过程 在Cat类里,注入People类,同样的创建一个People类,注入Cat类。People类省略了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Component public class Cat { public Cat () { System.out.println("cat 被创建" ); } private People people; @Autowired public void setPeople (People people) { this .people = people; } }
再看org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
的下面方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Override public PropertyValues postProcessProperties (PropertyValues pvs, Object bean, String beanName) { InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs); try { metadata.inject(bean, beanName, pvs); } catch (BeanCreationException ex) { throw ex; } catch (Throwable ex) { throw new BeanCreationException (beanName, "Injection of autowired dependencies failed" , ex); } return pvs; }
1 2 3 4 5 6 7 8 9 10 public void inject (Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { Collection<InjectedElement> checkedElements = this .checkedElements; Collection<InjectedElement> elementsToIterate = (checkedElements != null ? checkedElements : this .injectedElements); if (!elementsToIterate.isEmpty()) { for (InjectedElement element : elementsToIterate) { element.inject(target, beanName, pvs); } } }
注入的过程就是找到需要注入的方法或字段,如果是方法解析出对应的参数,让后尝试从工厂里获取参数对应的bean,如果工厂里没有,工厂就会自己创建。
上面的示例将会走如下逻辑
先初始化Cat ->需要注入Peoper但不存在 -> 创建People->People需要Cat进行注入向工厂要->工厂内已经有了Cat的实例,只是尚未初始化完成是个半成品,返回此半成品->people初始化完成 ->Cat初始化完成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 @Override protected void inject (Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { if (checkPropertySkipping(pvs)) { return ; } Method method = (Method) this .member; Object[] arguments; if (this .cached) { arguments = resolveCachedArguments(beanName); } else { Class<?>[] paramTypes = method.getParameterTypes(); arguments = new Object [paramTypes.length]; DependencyDescriptor[] descriptors = new DependencyDescriptor [paramTypes.length]; Set<String> autowiredBeans = new LinkedHashSet <>(paramTypes.length); Assert.state(beanFactory != null , "No BeanFactory available" ); TypeConverter typeConverter = beanFactory.getTypeConverter(); for (int i = 0 ; i < arguments.length; i++) { MethodParameter methodParam = new MethodParameter (method, i); DependencyDescriptor currDesc = new DependencyDescriptor (methodParam, this .required); currDesc.setContainingClass(bean.getClass()); descriptors[i] = currDesc; try { Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter); if (arg == null && !this .required) { arguments = null ; break ; } arguments[i] = arg; } catch (BeansException ex) { throw new UnsatisfiedDependencyException (null , beanName, new InjectionPoint (methodParam), ex); } } synchronized (this ) { if (!this .cached) { if (arguments != null ) { Object[] cachedMethodArguments = new Object [paramTypes.length]; System.arraycopy(descriptors, 0 , cachedMethodArguments, 0 , arguments.length); registerDependentBeans(beanName, autowiredBeans); if (autowiredBeans.size() == paramTypes.length) { Iterator<String> it = autowiredBeans.iterator(); for (int i = 0 ; i < paramTypes.length; i++) { String autowiredBeanName = it.next(); if (beanFactory.containsBean(autowiredBeanName) && beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) { cachedMethodArguments[i] = new ShortcutDependencyDescriptor ( descriptors[i], autowiredBeanName, paramTypes[i]); } } } this .cachedMethodArguments = cachedMethodArguments; } else { this .cachedMethodArguments = null ; } this .cached = true ; } } } if (arguments != null ) { try { ReflectionUtils.makeAccessible(method); method.invoke(bean, arguments); } catch (InvocationTargetException ex) { throw ex.getTargetException(); } } }
查看doGetBean方法里的getSingleton(beanName)调用
1 2 3 4 5 6 7 8 protected <T> T doGetBean (final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); Object bean; Object sharedInstance = getSingleton(beanName);
此方法将尝试获取尚未构建完成的Bean
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 protected Object getSingleton (String beanName, boolean allowEarlyReference) { Object singletonObject = this .singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this .singletonObjects) { singletonObject = this .earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { ObjectFactory<?> singletonFactory = this .singletonFactories.get(beanName); if (singletonFactory != null ) { singletonObject = singletonFactory.getObject(); this .earlySingletonObjects.put(beanName, singletonObject); this .singletonFactories.remove(beanName); } } } } return singletonObject; }
什么时候将尚未初始化的Bean放入map里的呢?
原来是创建完成后,尚未初始化前放入的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 protected Object doCreateBean (final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { BeanWrapper instanceWrapper = null ; instanceWrapper = createBeanInstance(beanName, mbd, args); final Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); return exposedObject; }