15.Spring整体流程(下)

132 阅读3分钟

初始化阶段:initializeBean()

protected Object initializeBean(String beanName, Object bean,@Nullable RootBeanDefinition mbd){
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
          //步骤1
         invokeAwareMethods(beanName, bean);
         return null;
      }, getAccessControlContext());
   }
   else {
      invokeAwareMethods(beanName, bean);
   }

   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
   //步骤2
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }

   try {
   //步骤3
      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()) {
       //步骤4
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }

   return wrappedBean;
}

主要是对应了代码注释里的4个步骤。

1.invokeAwareMethods

先上源码:

private void invokeAwareMethods(String beanName, 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);
      }
   }
}

发现主要是调用BeanNameAware#setBeanName、BeanClassLoaderAware#setBeanClassLoader以及BeanFactoryAware#setBeanFactory。

1.如果Bean实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,此处传递的就是Spring配置文件中Bean的id值。

2.如果Bean实现了BeanFactoryAware接口,会调用它实现的setBeanFactory()方法,传递的是Spring工厂自身。

3.如果Bea经实现了BeanClassLoaderAware接口,会调用setBeanClassLoader()方法,传入类加载器。

BeanNameAware、BeanClassLoaderAware、BeanFactoryAware 都实现了Aware接口,Aware接口是1个空接口。

2.BeanPostProcessor#postProcessBeforeInitialization

2.1执行ApplicationContextAwareProcessor

调用BeanPostProcessor的前置处理方法。其中有1个比较特殊的BeanPostProcessor。 它的类型是ApplicationContextAwareProcessor。

ApplicationContextAwareProcessor和其他的Aware不同。ApplicationContextAwareProcessor是1个BeanPostProcessor,调用ApplicationContextAware的postProcessBeforeInitialization方法最后调用的是ApplicationContextAware#setApplicationContext方法

先上源码:ApplicationContextAwareProcessor#postProcessBeforeInitialization

@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;
}

继续跟进 invokeAwareInterfaces(bean);

private void invokeAwareInterfaces(Object bean) {
   if (bean instanceof EnvironmentAware) {
      ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
   }
   if (bean instanceof EmbeddedValueResolverAware) {
      ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
   }
   if (bean instanceof ResourceLoaderAware) {
      ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
   }
   if (bean instanceof ApplicationEventPublisherAware) {
      ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
   }
   if (bean instanceof MessageSourceAware) {
      ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
   }
   if (bean instanceof ApplicationContextAware) {
      ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
   }
}

如果Bean实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文。

2.2执行CommonAnnotationBeanPostProcessor

先看CommonAnnotationBeanPostProcessor静态代码块和构造方法的源码

static {
    webServiceRefClass = loadAnnotationType("javax.xml.ws.WebServiceRef");
    ejbClass = loadAnnotationType("javax.ejb.EJB");

    resourceAnnotationTypes.add(Resource.class);
    if (webServiceRefClass != null) {
        resourceAnnotationTypes.add(webServiceRefClass);
    }
    if (ejbClass != null) {
        resourceAnnotationTypes.add(ejbClass);
    }
}

public CommonAnnotationBeanPostProcessor() {
    setOrder(Ordered.LOWEST_PRECEDENCE - 3);
    setInitAnnotationType(PostConstruct.class);
    setDestroyAnnotationType(PreDestroy.class);
    ignoreResourceType("javax.xml.ws.WebServiceContext");
}

从CommonAnnotationBeanPostProcessor静态代码块和构造方法可以大概猜出来,该BeanPostProcessor用于处理带@PostConstruct和@PreDestroy的方法以及@Resource注解。此处只是收集,并没有调用。调用在接下来的invokeInitMethods

我们知道如果想要自定义bean的初始化行为,有两种方法:

1.使用xml配置,在bean的xml定义中指定init-method属性。

2.注解配置,在bean的class定义中添加@PostConstruct注解。

具体可参考:blog.csdn.net/qq_43799161… ,此处不做太细致的介绍。

3.invokeInitMethods

直接上源码

protected void invokeInitMethods(String beanName, 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 {
          //调用afterPropertiesSet方法
         ((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)) {
         //调用自定义的init方法   
         invokeCustomInitMethod(beanName, bean, mbd);
      }
   }
}

3.1.InitializingBean#afterPropertiesSet

调用Bean的实现的InitializingBean接口的afterPropertiesSet方法

3.2.init方法

调用Bean的init方法

4.BeanPostProcessor#postProcessAfterInitialization

wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

4.1代理就是这里被生成的

个人感觉是最重要的BeanPostProcessor:AnnotationAwareAspectJAutoProxyCreator

主要用于生成代理和切面,这里也不做细讲。

5.SmartInitializingSingleton#afterSingletonsInstantiated

该方法会在非懒加载单实例bean成功创建并且放到Spring IOC容器之后,依次遍历所有的bean
如果当前这个bean是SmartInitializingSingleton的子类,那么就强转成SmartInitializingSingleton类,
然后调用SmartInitializingSingleton的afterSingletonsInstantiated方法。

执行EventListenerMethodProcessor

在实例的生命周期结束以后 
会遍历所有的bean
调用所有SmartInitializingSingleton的afterSingletonsInstantiated方法