spring-bean的创建过程
创建bean的方法
/*** Central method of this class: creates a bean instance,* populates the bean instance, applies post-processors, etc.* @see #doCreateBean*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");}RootBeanDefinition mbdToUse = mbd;// Make sure bean class is actually resolved at this point, and// clone the bean definition in case of a dynamically resolved Class// which cannot be stored in the shared merged bean definition.// 确保 BeanDefinition 中的 Class 被加载Class<?> resolvedClass = resolveBeanClass(mbd, beanName);if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);mbdToUse.setBeanClass(resolvedClass);}// Prepare method overrides.// 准备方法覆写,这里又涉及到一个概念:MethodOverrides,它来自于 bean 定义中的 <lookup-method />// 和 <replaced-method />,如果读者感兴趣,回到 bean 解析的地方看看对这两个标签的解析。// 我在附录中也对这两个标签的相关知识点进行了介绍,读者可以移步去看看try {
// 让 InstantiationAwareBeanPostProcessor 在这一步有机会返回代理,// 在 《Spring AOP 源码分析》那篇文章中有解释,这里先跳过mbdToUse.prepareMethodOverrides();}catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),beanName, "Validation of method overrides failed", ex);}try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.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);}try {
// 重头戏,创建 beanObject beanInstance = doCreateBean(beanName, mbdToUse, args);if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");}return beanInstance;}catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.throw ex;}catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);}
}
创建 Bean 实例
doCreateBean.createBeanInstance
不是 FactoryBean,这里实例化 Bean;
-
instantiateUsingFactoryMethod 采用工厂方法实例化,,注意,不是 FactoryBean
-
判断是否是第一次创建 ,比如第二次创建 prototype bean。 这种情况下,我们可以从第一次创建知道,采用无参构造函数,还是构造函数依赖注入 来完成实例化
-
boolean resolved = false;boolean autowireNecessary = false;if (args == null) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true;autowireNecessary = mbd.constructorArgumentsResolved;}}}if (resolved) { if (autowireNecessary) { // 构造函数依赖注入return autowireConstructor(beanName, mbd, null, null);}else { // 无参构造函数return instantiateBean(beanName, mbd);}}// 判断是否采用有参构造函数Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);if (ctors != null ||mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { // 构造函数依赖注入return autowireConstructor(beanName, mbd, ctors, args);}// 调用无参构造函数return instantiateBean(beanName, mbd);
-
看看无参数构造函数吧 instantiateBean
-
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) { try { Object beanInstance;final BeanFactory parent = this;if (System.getSecurityManager() != null) { beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->getInstantiationStrategy().instantiate(mbd, beanName, parent),getAccessControlContext());}else { // 实例化beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);}// 包装一下,返回BeanWrapper bw = new BeanWrapperImpl(beanInstance);initBeanWrapper(bw);return bw;}catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);} }
-
进入 getInstantiationStrategy().instantiate(mbd, beanName, parent); 实例化
@Override public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) { // Don't override the class with CGLIB if no overrides.// 如果不存在方法覆写,那就使用 java 反射进行实例化,否则使用 CGLIB,// 方法覆写 请参见附录"方法注入"中对 lookup-method 和 replaced-method 的介绍if (!bd.hasMethodOverrides()) { Constructor<?> constructorToUse;synchronized (bd.constructorArgumentLock) { constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;if (constructorToUse == null) { final Class<?> clazz = bd.getBeanClass();if (clazz.isInterface()) { throw new BeanInstantiationException(clazz, "Specified class is an interface");}try { if (System.getSecurityManager() != null) { constructorToUse = AccessController.doPrivileged((PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);}else { constructorToUse = clazz.getDeclaredConstructor();}bd.resolvedConstructorOrFactoryMethod = constructorToUse;}catch (Throwable ex) { throw new BeanInstantiationException(clazz, "No default constructor found", ex);}}}// 利用构造方法进行实例化return BeanUtils.instantiateClass(constructorToUse);}else { // Must generate CGLIB subclass.// 存在方法覆写,利用 CGLIB 来完成实例化,需要依赖于 CGLIB 生成子类,这里就不展开了。// tips: 因为如果不使用 CGLIB 的话,存在 override 的情况 JDK 并没有提供相应的实例化支持return instantiateWithMethodInjection(bd, beanName, owner);} }
创建 Bean 实例
? 看完了 createBeanInstance(…) 方法,我们来看看 populateBean(…) 方法,该方法负责进行属性设值,处理依赖。
/*** Populate the bean instance in the given BeanWrapper with the property values* from the bean definition.* @param beanName the name of the bean* @param mbd the bean definition for the bean* @param bw the BeanWrapper with bean instance*/
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 {
// Skip property population phase for null instance.//空属性直接returnreturn;}}// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the// state of the bean before properties are set. This can be used, for example,// to support styles of field injection.// 到这步的时候,bean 实例化完成(通过工厂方法或构造方法),但是还没开始属性设值,// InstantiationAwareBeanPostProcessor 的实现类可以在这里对 bean 进行状态修改,// 我也没找到有实际的使用,所以我们暂且忽略这块吧if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
// 如果返回 false,代表不需要进行后续的属性设值,也不需要再经过其他的 BeanPostProcessor 的处理if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;}}}}// bean 实例的所有属性都在这里了PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);int resolvedAutowireMode = mbd.getResolvedAutowireMode();if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);// Add property values based on autowire by name if applicable.//@Resources按名字,是JDK的,@Autowired按类型,是Spring的。// 通过名字找到所有属性值,如果是 bean 依赖,先初始化依赖的 bean。记录依赖关系if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);}// 通过类型装配。复杂一些// Add property values based on autowire by type if applicable.if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);}pvs = newPvs;}boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();}PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;// 这里有个非常有用的 BeanPostProcessor 进到这里: AutowiredAnnotationBeanPostProcessor// 对采用 @Autowired、@Value 注解的依赖进行设值,这里的内容也是非常丰富的,不过本文不会展开说了,感兴趣的读者请自行研究//CommonAnnotationBeanPostProcessor是处理@ReSource注解的//AutoWiredAnnotationBeanPostProcessor是处理@AutoWired注解的pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);if (pvs == null) {
return;}}}}if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);}}if (pvs != null) {
// 设置 bean 实例的属性值applyPropertyValues(beanName, mbd, bw, pvs);}
}
- applyPropertyValues 设置bean实例属性方法
initializeBean
初始化bean
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);return null;}, getAccessControlContext());}else {
// 如果 bean 实现了 BeanNameAware、BeanClassLoaderAware 或 BeanFactoryAware 接口,回调invokeAwareMethods(beanName, bean);}Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {
// BeanPostProcessor 的 postProcessBeforeInitialization 回调wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {
// 处理 bean 中定义的 init-method,// 或者如果 bean 实现了 InitializingBean 接口,调用 afterPropertiesSet() 方法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()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;
}