美文网首页
Spring Bean生命周期

Spring Bean生命周期

作者: Johar77 | 来源:发表于2020-07-14 00:06 被阅读0次

    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() 方法、自定义销毁方法

    相关文章

      网友评论

          本文标题:Spring Bean生命周期

          本文链接:https://www.haomeiwen.com/subject/ygpthktx.html