Spring Bean生命周期

2020-07-14  本文已影响0人  Johar77

Spring Bean生命周期

1.BeanDefinition

Spring中对象皆为bean,进而将bean的定义信息进行抽象为BeanDefinition,将BeanDefinition作为标准进行创建。一般情况下,可以通过可以通过如下的方式进行配置:

1.1 面向资源

1.1.1 XML配置

使用BeanDefinitionReader进行读取资源。xml的配置一般如下所示:

<bean id="user" class="com.johar.thinkinspring.ioc.dependency.domain.User">

    <property name="id" value="1"/>

    <property name="name" value="johar"/>

</bean>

该类的解析方式如下:

public static void main(String[] args){

    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);

    String location = "classpath:/dependency-lookup-context.xml";

    int beanDefinitionCount = reader.loadBeanDefinitions(location);

    System.out.println("Bean定义加载的数量:" + beanDefinitionCount);

    lookupCollectionByType(beanFactory);

}

private static void lookupCollectionByType(BeanFactory beanFactory){

    if (beanFactory instanceof ListableBeanFactory){

        ListableBeanFactory listableBeanFactory = (ListableBeanFactory)beanFactory;

        Map<String, User> userMap = listableBeanFactory.getBeansOfType(User.class);

        System.out.println("查找所有的User集合:" + userMap);

    }

}

1.1.2 Properties资源配置

Properties资源使用PropertiesBeanDefinitionReader读取资源,源码中PropertiesBeanDefinitionReader配置实例如下:

代码实例如下:

user.(class)=com.johar.thinkinspring.ioc.dependency.domain.User

user.id = 100

user.name = 实例

测试代码如下:

public static void main(String[] args) {

    DefaultListableBeanFactory factory = new DefaultListableBeanFactory();

    PropertiesBeanDefinitionReader reader = new PropertiesBeanDefinitionReader(factory);

    String xmlPath = "user.properties";

    ClassPathResource resource = new ClassPathResource(xmlPath);

    EncodedResource encodedResource = new EncodedResource(resource, "UTF-8");

    int beanNum = reader.loadBeanDefinitions(encodedResource);

    System.out.printf("load bean num = " + beanNum);

    User user = factory.getBean(User.class);

    System.out.println(user);

}

有个地方需要注意一下,PropertiesBeanDefinitionReader默认安装ASCII读取,但是user.properties文件使用utf-8编码。

1.2 面向注解

public class AnnotatedBeanDefinitionParseDemo {

    public static void main(String[] args) {

        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

        AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(beanFactory);

        reader.register(AnnotatedBeanDefinitionParseDemo.class);

        AnnotatedBeanDefinitionParseDemo demo = beanFactory.getBean(AnnotatedBeanDefinitionParseDemo.class);

        System.out.println(demo);

    }

}

1.3 面向API

BeanDefinitionRegistry

public static void main(String[] args){

    BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);

    beanDefinitionBuilder.addPropertyValue("id", 1);

    beanDefinitionBuilder.addPropertyValue("name", "Johar");

    BeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();

    GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();

    genericBeanDefinition.setBeanClass(User.class);

    MutablePropertyValues propertyValues = new MutablePropertyValues();

    propertyValues.add("id", 1);

    propertyValues.add("name", "Johar");

    genericBeanDefinition.setPropertyValues(propertyValues);

}

2.Spring Bean生命周期

Spring Bean的生命周期主要看AbstractApplicationContext的refresh()方法。

@Override

public void refresh() throws BeansException, IllegalStateException {

  synchronized (this.startupShutdownMonitor) {

      // Prepare this context for refreshing.

      // 容器刷新前的准备,设置上下文状态,获取属性,验证必要的属性等

      prepareRefresh();

      // Tell the subclass to refresh the internal bean factory.

      // 获取新的beanFactory,销毁原有beanFactory、为每个bean生成BeanDefinition等

      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.

      // 配置标准的beanFactory,设置ClassLoader,设置SpEL表达式解析器,添加忽略注入的接口,添加bean,添加bean后置处理器等

      prepareBeanFactory(beanFactory);

      try {

        // Allows post-processing of the bean factory in context subclasses.

        // 模板方法,此时,所有的beanDefinition已经加载,但是还没有实例化。

        // 允许在子类中对beanFactory进行扩展处理。比如添加ware相关接口自动装配设置,添加后置处理器等,是子类扩展prepareBeanFactory(beanFactory)的方

        postProcessBeanFactory(beanFactory);

        // Invoke factory processors registered as beans in the context.

        // 实例化并调用所有注册的beanFactory后置处理器(实现接口BeanFactoryPostProcessor的bean,在beanFactory标准初始化之后执行)

        invokeBeanFactoryPostProcessors(beanFactory);

        // Register bean processors that intercept bean creation.

        //

        registerBeanPostProcessors(beanFactory);

        // Initialize message source for this context.

        initMessageSource();

        // Initialize event multicaster for this context.

        initApplicationEventMulticaster();

        // Initialize other special beans in specific context subclasses.

        onRefresh();

        // Check for listener beans and register them.

        registerListeners();

        // Instantiate all remaining (non-lazy-init) singletons.

        finishBeanFactoryInitialization(beanFactory);

        // Last step: publish corresponding event.

        finishRefresh();

      }

      catch (BeansException ex) {

        if (logger.isWarnEnabled()) {

            logger.warn("Exception encountered during context initialization - " +

                  "cancelling refresh attempt: " + ex);

        }

        // Destroy already created singletons to avoid dangling resources.

        destroyBeans();

        // Reset 'active' flag.

        cancelRefresh(ex);

        // Propagate exception to caller.

        throw ex;

      }

      finally {

        // Reset common introspection caches in Spring's core, since we

        // might not ever need metadata for singleton beans anymore...

        resetCommonCaches();

      }

  }

}

在finishBeanFactoryInitialization中实例化非lazy加载的bean。另外Spring中ApplicationContext中实际使用的DefaultListableBeanFactory

2.1 BeanDefinition注册-registerBeanDefinition

@Override

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)

      throws BeanDefinitionStoreException {

  Assert.hasText(beanName, "Bean name must not be empty");

  Assert.notNull(beanDefinition, "BeanDefinition must not be null");

  if (beanDefinition instanceof AbstractBeanDefinition) {

      try {

        ((AbstractBeanDefinition) beanDefinition).validate();

      }

      catch (BeanDefinitionValidationException ex) {

        throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,

              "Validation of bean definition failed", ex);

      }

  }

  BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);

  if (existingDefinition != null) {

      if (!isAllowBeanDefinitionOverriding()) {

        throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);

      }

      else if (existingDefinition.getRole() < beanDefinition.getRole()) {

        // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE

        if (logger.isInfoEnabled()) {

            logger.info("Overriding user-defined bean definition for bean '" + beanName +

                  "' with a framework-generated bean definition: replacing [" +

                  existingDefinition + "] with [" + beanDefinition + "]");

        }

      }

      else if (!beanDefinition.equals(existingDefinition)) {

        if (logger.isDebugEnabled()) {

            logger.debug("Overriding bean definition for bean '" + beanName +

                  "' with a different definition: replacing [" + existingDefinition +

                  "] with [" + beanDefinition + "]");

        }

      }

      else {

        if (logger.isTraceEnabled()) {

            logger.trace("Overriding bean definition for bean '" + beanName +

                  "' with an equivalent definition: replacing [" + existingDefinition +

                  "] with [" + beanDefinition + "]");

        }

      }

      this.beanDefinitionMap.put(beanName, beanDefinition);

  }

  else {

      if (hasBeanCreationStarted()) {

        // Cannot modify startup-time collection elements anymore (for stable iteration)

        synchronized (this.beanDefinitionMap) {

            this.beanDefinitionMap.put(beanName, beanDefinition);

            List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);

            updatedDefinitions.addAll(this.beanDefinitionNames);

            updatedDefinitions.add(beanName);

            this.beanDefinitionNames = updatedDefinitions;

            removeManualSingletonName(beanName);

        }

      }

      else {

        // Still in startup registration phase

        this.beanDefinitionMap.put(beanName, beanDefinition);

        this.beanDefinitionNames.add(beanName);

        removeManualSingletonName(beanName);

      }

      this.frozenBeanDefinitionNames = null;

  }

  if (existingDefinition != null || containsSingleton(beanName)) {

      resetBeanDefinition(beanName);

  }

  else if (isConfigurationFrozen()) {

      clearByTypeCache();

  }

}

2.2 BeanDefinition合并-getMergedBeanDefinition

父子BeanDefinition合并,先查找父BeanFactory,最后查找本地。

@Override

public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {

  String beanName = transformedBeanName(name);

  // Efficiently check whether bean definition exists in this factory.

  if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {

      return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);

  }

  // Resolve merged bean definition locally.

  return getMergedLocalBeanDefinition(beanName);

}

2.3 Bean实例化前阶段-resolveBeforeInstantition

主要是执行InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation,若有返回,直接退出。

@Nullable

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {

  Object bean = null;

  if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {

      // Make sure bean class is actually resolved at this point.

      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;

}

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);

}

2.4 Bean 实例化阶段 - createBeanInstance

使用instantiationstrategy创建bean实例,instantiationstrategy包括:factory method, constructor autowiring, or simple instantiation(CglibSubclassingInstantiationStrategy)

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {

  // Make sure bean class is actually resolved at this point.

  Class<?> beanClass = resolveBeanClass(mbd, beanName);

  if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {

      throw new BeanCreationException(mbd.getResourceDescription(), beanName,

            "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());

  }

  Supplier<?> instanceSupplier = mbd.getInstanceSupplier();

  if (instanceSupplier != null) {

      return obtainFromSupplier(instanceSupplier, beanName);

  }

  if (mbd.getFactoryMethodName() != null) {

      return instantiateUsingFactoryMethod(beanName, mbd, args);

  }

  // Shortcut when re-creating the same 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);

      }

  }

  // Candidate constructors for autowiring?

  Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);

  if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||

        mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {

      return autowireConstructor(beanName, mbd, ctors, args);

  }

  // Preferred constructors for default construction?

  ctors = mbd.getPreferredConstructors();

  if (ctors != null) {

      return autowireConstructor(beanName, mbd, ctors, null);

  }

  // No special handling: simply use no-arg constructor.

  return instantiateBean(beanName, mbd);

}

2.5 Bean 实例化后阶段 - populateBean

InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation

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.

        return;

      }

  }

  // 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.

  if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {

      for (BeanPostProcessor bp : getBeanPostProcessors()) {

        if (bp instanceof InstantiationAwareBeanPostProcessor) {

            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

            if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {

              return;

            }

        }

      }

  }

  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.

      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);

  PropertyDescriptor[] filteredPds = null;

  if (hasInstAwareBpps) {

      if (pvs == null) {

        pvs = mbd.getPropertyValues();

      }

      for (BeanPostProcessor bp : getBeanPostProcessors()) {

        if (bp instanceof InstantiationAwareBeanPostProcessor) {

            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

            PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);

            if (pvsToUse == null) {

              if (filteredPds == null) {

                  filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);

              }

              pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);

              if (pvsToUse == null) {

                  return;

              }

            }

            pvs = pvsToUse;

        }

      }

  }

  if (needsDepCheck) {

      if (filteredPds == null) {

        filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);

      }

      checkDependencies(beanName, mbd, filteredPds, pvs);

  }

  if (pvs != null) {

      applyPropertyValues(beanName, mbd, bw, pvs);

  }

}

2.6 Bean 属性赋值前阶段 - populateBean

Bean属性值元信息PropertyValues

Spring 5.1及以上:InstantiationAwareBeanPostProcessor#postProcessProperties

Spring 1.2-5.0 InstantiationAwareBeanPostProcessor#postProcessPropertyValues

2.7 Bean 属性赋值阶段 - populateBean

AbstractAutowireCapableBeanFactory#applyPropertyValues

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {

  if (pvs.isEmpty()) {

      return;

  }

  if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {

      ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());

  }

  MutablePropertyValues mpvs = null;

  List<PropertyValue> original;

  if (pvs instanceof MutablePropertyValues) {

      mpvs = (MutablePropertyValues) pvs;

      if (mpvs.isConverted()) {

        // Shortcut: use the pre-converted values as-is.

        try {

            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);

  // Create a deep copy, resolving any references for values.

  List<PropertyValue> deepCopy = new ArrayList<>(original.size());

  boolean resolveNecessary = false;

  for (PropertyValue pv : original) {

      if (pv.isConverted()) {

        deepCopy.add(pv);

      }

      else {

        String propertyName = pv.getName();

        Object originalValue = pv.getValue();

        if (originalValue == AutowiredPropertyMarker.INSTANCE) {

            Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();

            if (writeMethod == null) {

              throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);

            }

            originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);

        }

        Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);

        Object convertedValue = resolvedValue;

        boolean convertible = bw.isWritableProperty(propertyName) &&

              !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);

        if (convertible) {

            convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);

        }

        // Possibly store converted value in merged bean definition,

        // in order to avoid re-conversion for every created bean instance.

        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));

        }

      }

  }

  if (mpvs != null && !resolveNecessary) {

      mpvs.setConverted();

  }

  // Set our (possibly massaged) deep copy.

  try {

      bw.setPropertyValues(new MutablePropertyValues(deepCopy));

  }

  catch (BeansException ex) {

      throw new BeanCreationException(

            mbd.getResourceDescription(), beanName, "Error setting property values", ex);

  }

}

2.8 Bean Aware 接口回调阶段 - initializeBean

AbstractAutowireCapableBeanFactory#invokeAwareMethods中依次BeanNameAware,BeanClassLoaderAware,BeanFactoryAware

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);

      }

  }

}

ApplicationContextAwareProcessor#postProcessorBeforeInitialization依次调用了EnvironmentAware,EmbeddedValueResolverAware,ResourceLoaderAware,ApplicationEventPublisherAware,MessageSourceAware,ApplicationContextAware

@Override

@Nullable

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 (System.getSecurityManager() != null) {

      acc = this.applicationContext.getBeanFactory().getAccessControlContext();

  }

  if (acc != null) {

      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {

        invokeAwareInterfaces(bean);

        return null;

      }, acc);

  }

  else {

      invokeAwareInterfaces(bean);

  }

  return bean;

}

2.9 Bean 初始化前阶段 - initializeBean

BeanPostProcessor#postProcessBeforeInitialization

@Override

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;

}

2.10 Bean 初始化阶段 - initializeBean

@PostConstruct 标注方法

必须加上CommonAnnotationBeanPostProcessor,在InitDestroyAnnotationBeanPostProcessor#postProcessBeforeInitialization

@Override

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

  LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());

  try {

      metadata.invokeInitMethods(bean, beanName);

  }

  catch (InvocationTargetException ex) {

      throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());

  }

  catch (Throwable ex) {

      throw new BeanCreationException(beanName, "Failed to invoke init method", ex);

  }

  re

实现 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 + "'");

      }

      if (System.getSecurityManager() != null) {

        try {

            AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {

              ((InitializingBean) bean).afterPropertiesSet();

              return null;

            }, getAccessControlContext());

        }

        catch (PrivilegedActionException pae) {

            throw pae.getException();

        }

      }

      else {

        ((InitializingBean) bean).afterPropertiesSet();

      }

  }

  if (mbd != null && bean.getClass() != NullBean.class) {

      String initMethodName = mbd.getInitMethodName();

      if (StringUtils.hasLength(initMethodName) &&

            !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&

            !mbd.isExternallyManagedInitMethod(initMethodName)) {

        invokeCustomInitMethod(beanName, bean, mbd);

      }

  }

}

自定义初始化方法

protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd)

      throws Throwable {

  String initMethodName = mbd.getInitMethodName();

  Assert.state(initMethodName != null, "No init method set");

  Method initMethod = (mbd.isNonPublicAccessAllowed() ?

        BeanUtils.findMethod(bean.getClass(), initMethodName) :

        ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));

  if (initMethod == null) {

      if (mbd.isEnforceInitMethod()) {

        throw new BeanDefinitionValidationException("Could not find an init method named '" +

              initMethodName + "' on bean with name '" + beanName + "'");

      }

      else {

        if (logger.isTraceEnabled()) {

            logger.trace("No default init method named '" + initMethodName +

                  "' found on bean with name '" + beanName + "'");

        }

        // Ignore non-existent default lifecycle methods.

        return;

      }

  }

  if (logger.isTraceEnabled()) {

      logger.trace("Invoking init method  '" + initMethodName + "' on bean with name '" + beanName + "'");

  }

  Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);

  if (System.getSecurityManager() != null) {

      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {

        ReflectionUtils.makeAccessible(methodToInvoke);

        return null;

      });

      try {

        AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->

              methodToInvoke.invoke(bean), getAccessControlContext());

      }

      catch (PrivilegedActionException pae) {

        InvocationTargetException ex = (InvocationTargetException) pae.getException();

        throw ex.getTargetException();

      }

  }

  else {

      try {

        ReflectionUtils.makeAccessible(methodToInvoke);

        methodToInvoke.invoke(bean);

      }

      catch (InvocationTargetException ex) {

        throw ex.getTargetException();

      }

  }

}

2.11 Bean 初始化后阶段 - initializeBean

BeanPostProcessor#postProcessAfterInitialization

@Override

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)

      throws BeansException {

  Object result = existingBean;

  for (BeanPostProcessor processor : getBeanPostProcessors()) {

      Object current = processor.postProcessAfterInitialization(result, beanName);

      if (current == null) {

        return result;

      }

      result = current;

  }

  return result;

}

2.12 Bean 初始化完成阶段 - preInstantiateSingletons

SmartInitializingSingleton#afterSingletonsInstantiated

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {

  // Initialize conversion service for this context.

  if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&

        beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {

      beanFactory.setConversionService(

            beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));

  }

  // Register a default embedded value resolver if no bean post-processor

  // (such as a PropertyPlaceholderConfigurer bean) registered any before:

  // at this point, primarily for resolution in annotation attribute values.

  if (!beanFactory.hasEmbeddedValueResolver()) {

      beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));

  }

  // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.

  String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);

  for (String weaverAwareName : weaverAwareNames) {

      getBean(weaverAwareName);

  }

  // Stop using the temporary ClassLoader for type matching.

  beanFactory.setTempClassLoader(null);

  // Allow for caching all bean definition metadata, not expecting further changes.

  beanFactory.freezeConfiguration();

  // Instantiate all remaining (non-lazy-init) singletons.

  beanFactory.preInstantiateSingletons();

}

2.13 Bean 销毁前阶段 - destroyBean

DestructionAwareBeanPostProcessor#postProcessBeforeDestruction

在DisposableBeanAdapter#destroy中调用

public void destroy() {

  if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {

      for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {

        processor.postProcessBeforeDestruction(this.bean, this.beanName);

      }

  }

  if (this.invokeDisposableBean) {

      if (logger.isTraceEnabled()) {

        logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");

      }

      try {

        if (System.getSecurityManager() != null) {

            AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {

              ((DisposableBean) this.bean).destroy();

              return null;

            }, this.acc);

        }

        else {

            ((DisposableBean) this.bean).destroy();

        }

      }

      catch (Throwable ex) {

        String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";

        if (logger.isDebugEnabled()) {

            logger.warn(msg, ex);

        }

        else {

            logger.warn(msg + ": " + ex);

        }

      }

  }

  if (this.destroyMethod != null) {

      invokeCustomDestroyMethod(this.destroyMethod);

  }

  else if (this.destroyMethodName != null) {

      Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);

      if (methodToInvoke != null) {

        invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));

      }

  }

}

2.14 Bean 销毁阶段 - destroyBean

依次调用:@PreDestroy 标注方法、实现 DisposableBean 接口的 destroy() 方法、自定义销毁方法

上一篇下一篇

猜你喜欢

热点阅读