深入理解Spring IOC(六)、 bean的填充以及初始化工作(下)

简介: 深入理解Spring IOC(六)、 bean的填充以及初始化工作(下)

代码块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加载的整个流程。

目录
相关文章
|
5天前
|
XML Java 数据格式
【SpringFramework】Spring IoC-基于XML的实现
本文主要讲解SpringFramework中IoC和DI相关概念,及基于XML的实现方式。
96 69
|
3天前
|
Java Spring 容器
【SpringFramework】Spring IoC-基于注解的实现
本文主要记录基于Spring注解实现IoC容器和DI相关知识。
36 21
|
8天前
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
|
8天前
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
|
7月前
|
Java 开发者 Spring
解析Spring中Bean的生命周期
解析Spring中Bean的生命周期
64 2
|
7月前
|
XML druid Java
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
75 0
|
3月前
|
Java 开发者 Spring
Spring bean的生命周期详解!
本文详细解析Spring Bean的生命周期及其核心概念,并深入源码分析。Spring Bean是Spring框架的核心,由容器管理其生命周期。从实例化到销毁,共经历十个阶段,包括属性赋值、接口回调、初始化及销毁等。通过剖析`BeanFactory`、`ApplicationContext`等关键接口与类,帮助你深入了解Spring Bean的管理机制。希望本文能助你更好地掌握Spring Bean生命周期。
147 1
|
3月前
|
Java 开发者 Spring
Spring bean的生命周期详解!
本文详细介绍了Spring框架中的核心概念——Spring Bean的生命周期,包括实例化、属性赋值、接口回调、初始化、使用及销毁等10个阶段,并深入剖析了相关源码,如`BeanFactory`、`DefaultListableBeanFactory`和`BeanPostProcessor`等关键类与接口。通过理解这些核心组件,读者可以更好地掌握Spring Bean的管理和控制机制。
112 1
|
6月前
|
Java Spring 容器
Spring Boot 启动源码解析结合Spring Bean生命周期分析
Spring Boot 启动源码解析结合Spring Bean生命周期分析
117 11
|
5月前
|
前端开发 Java 开发者