代码块3中3处
到了3.3这里,spring已经知道了bean的哪个属性需要注入,并且注入的值已经拿到,我们来看看这里的代码:
代码块6 protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { // 如果pvs为空过直接返回 if (pvs == null || pvs.isEmpty()) { return; } MutablePropertyValues mpvs = null; List<PropertyValue> original; if (System.getSecurityManager() != null) { if (bw instanceof BeanWrapperImpl) { ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext()); } } if (pvs instanceof MutablePropertyValues) { mpvs = (MutablePropertyValues) pvs; // 如果mpvs的属性值已经被转换成为对应的类型,则可以直接去设置 if (mpvs.isConverted()) { try { // 这里也是为什么使用BeanWrapper而不是使用beanInstance的原因 // 因为BeanWrapper实现了PropertyAccessor接口,可以直接给set值 // 这块有兴趣的可以自行研究一下 bw.setPropertyValues(mpvs); return; }catch (BeansException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Error setting property values", ex); } } original = mpvs.getPropertyValueList(); }else { // 获取原始的属性 original = Arrays.asList(pvs.getPropertyValues()); } TypeConverter converter = getCustomTypeConverter(); if (converter == null) { converter = bw; } // 获取解析器 BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter); // 对原始属性进行深拷贝,避免修改后引起的原始属性值修改 // deepcopy是后边直接用作给bean填充属性的 List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size()); boolean resolveNecessary = false; for (PropertyValue pv : original) { // 如果某个属性被转换过则直接加入deepCopy if (pv.isConverted()) { deepCopy.add(pv); // 否则的话进行转换 }else { // 拿到原始属性值和属性名称 String propertyName = pv.getName(); Object originalValue = pv.getValue(); // 并进行解析,并进行必要的解析 Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue); Object convertedValue = resolvedValue; // propertyName对应的属性是个可以写的 && 不能是嵌套属性或者下标属性 boolean convertible = bw.isWritableProperty(propertyName) && !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName); if (convertible) { convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter); } // 将转换过的值存起来避免重新转换 if (resolvedValue == originalValue) { if (convertible) { pv.setConvertedValue(convertedValue); } deepCopy.add(pv); }else if (convertible && originalValue instanceof TypedStringValue && !((TypedStringValue) originalValue).isDynamic() && !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) { pv.setConvertedValue(convertedValue); deepCopy.add(pv); }else { resolveNecessary = true; deepCopy.add(new PropertyValue(pv, convertedValue)); } } } // 将converted设置为true if (mpvs != null && !resolveNecessary) { mpvs.setConverted(); } // 用deepCopy里的值来进行属性填充 try { bw.setPropertyValues(new MutablePropertyValues(deepCopy)); }catch (BeansException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Error setting property values", ex); } }
这下doCreateBean中对bean的填充也完了,其实对bean的工作都是在BeanPostProcessor中完成的,在populateBean这个方法中只是对BeanPostProcessor的方法进行了调用而已。我们继续看1.4处,这个方法主要是针对bean的初始化的。
代码块1中4处
代码块7 protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { // 调用几个Aware接口 if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { // 1.调用aware invokeAwareMethods(beanName, bean); return null; } }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } // 2.调用所有的BeanPostProcessor的postProcessBeforeInitialization Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // 3.调用InitializingBean的方法和自定义初始化方法 invokeInitMethods(beanName, wrappedBean, mbd); }catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } // 4.执行所有BeanPostProcessor的postProcessAfterInitialization方法 if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
第1处主要是调用aware接口,aware接口我也会去写文章专门介绍,我们这会先来看这个方法做了什么:
代码块7中1处
代码块8 private void invokeAwareMethods(final String beanName, final Object bean) { // 所谓的xxxAware,就是让这个bean和xxx产生关联 if (bean instanceof Aware) { // 设置名称 if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } // 类加载器 if (bean instanceof BeanClassLoaderAware) { ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader()); } // 我们有时候使用BeanFactoryAware去拿BeanFactory,就是在这步设置的 if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } }
代码块7中2处
代码块9 public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; // 调用所有的BeanPostProcessor的postProcessBeforeInitialization(前置处理)方法 // 其中@PostConstruct就是在CommonAnnotationBeanPostProcessor中执行的 for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { result = beanProcessor.postProcessBeforeInitialization(result, beanName); if (result == null) { return result; } } return result; }
代码块7中3处
这个方法主要是执行初始化方法,主要执行@InitialBean中的初始化方法和自定义的初始化方法:
代码块10 protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable { // 调用InitializingBean的afterPropertiesSet方法,还是特权调用和普通调用 boolean isInitializingBean = (bean instanceof InitializingBean); if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { if (logger.isDebugEnabled()) { logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'"); } if (System.getSecurityManager() != null) { try { AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { @Override public Object run() throws Exception { // ((InitializingBean) bean).afterPropertiesSet(); return null; } }, getAccessControlContext()); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { ((InitializingBean) bean).afterPropertiesSet(); } } if (mbd != null) { String initMethodName = mbd.getInitMethodName(); if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { // 调用自定义的初始化方法,主要是通过反射调用 invokeCustomInitMethod(beanName, bean, mbd); } } }
代码块7中4处
这个方法也是初始化的最后一步
代码块11 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { // 执行所有BeanPostProcessor的postProcessAfterInitialization(后置处理)方法 Object result = existingBean; // 遍历执行 for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { result = beanProcessor.postProcessAfterInitialization(result, beanName); if (result == null) { return result; } } return result; }
至此,xml中bean的加载解析我们已经讲完,下一篇,我们将对整个流程做个总结,以及扩充一些面试涉及到的点,以让你更好的理解bean加载的整个流程。