Spring5.0源碼深度解析之Spring基於註解啓動流程分析

主要內容:

一、IOC容器的初始化流

  • 創建IOC容器

  • 註冊配置類

  • BeanFactory後置處理器

  • Bean的後置處理器

  • 創建Bean對象

IOC容器的初始化流程

從:

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);

進入:

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
   this();
   register(annotatedClasses);
   refresh();
}

一:創建IOC容器

1.this():先執行父類的初始化方法,創建IOC容器

public GenericApplicationContext() {
   this.beanFactory = new DefaultListableBeanFactory();
}

2.執行初始化方法創建BeanDefinition讀取器和classPath下掃描器

public AnnotationConfigApplicationContext() {
   this.reader = new AnnotatedBeanDefinitionReader(this);
   this.scanner = new ClassPathBeanDefinitionScanner(this);
}

3.this.reader = new AnnotatedBeanDefinitionReader(this)的創建過程:

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
   this(registry, getOrCreateEnvironment(registry));
}

4.執行AnnotatedBeanDefinitionReader的構造器:重點在最後一行的註冊註解配置處理器

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
   Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
   Assert.notNull(environment, "Environment must not be null");
   this.registry = registry;
   this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
   AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); //註冊註解配置處理器
}

5.1這個方法把下面對象註冊到IOC容器裏面

5.2ConfigurationClassPostProcessor對象註冊的代碼

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
      BeanDefinitionRegistry registry, @Nullable Object source) {

   DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);    //創建IOC容器
   ....
   Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(4);
   if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { //註冊5.2ConfigurationClassPostProcessor對象到IOC容器中
      RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
   }

6、執行this.scanner = new ClassPathBeanDefinitionScanner(this);

先走父類

public ClassPathScanningCandidateComponentProvider(boolean useDefaultFilters) {
   this(useDefaultFilters, new StandardEnvironment());
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
   this(registry, true);
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
   this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
      Environment environment) {

   this(registry, useDefaultFilters, environment,
         (registry instanceof ResourceLoader ? (ResourceLoader) registry : null));
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
      Environment environment, @Nullable ResourceLoader resourceLoader) {

   Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
   this.registry = registry;

   if (useDefaultFilters) {
      registerDefaultFilters();
   }
   setEnvironment(environment);
   setResourceLoader(resourceLoader);
}
protected void registerDefaultFilters() {
   this.includeFilters.add(new AnnotationTypeFilter(Component.class));
   ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
   try {
      this.includeFilters.add(new AnnotationTypeFilter(
            ((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
      logger.debug("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
   }
   catch (ClassNotFoundException ex) {
      // JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
   }
   try {
      this.includeFilters.add(new AnnotationTypeFilter(
            ((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
      logger.debug("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
   }
   catch (ClassNotFoundException ex) {
      // JSR-330 API not available - simply skip.
   }
}

registerDefaultFilters()把加了@Component註解的的class對象添加到includeFilters列表

問題1:加了@Component註解的類是怎麼註冊到SpringIOC容器裏面的?

二:註冊配置類

1.register(annotatedClasses);把用戶指定的類加載到IOC容器裏面

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
   this();
   register(annotatedClasses);
   refresh();
}
public void register(Class<?>... annotatedClasses) {
   Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
   this.reader.register(annotatedClasses);
}

2.進入上面創建的reader的註冊方法裏面

public void register(Class<?>... annotatedClasses) {
   for (Class<?> annotatedClass : annotatedClasses) {
      registerBean(annotatedClass);
   }
}
public void registerBean(Class<?> annotatedClass) {
   doRegisterBean(annotatedClass, null, null, null);
}
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
      @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {

   AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);//創建BeanDefinition對象
   if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {    //處理 @Condition註解
      return;
   }

   abd.setInstanceSupplier(instanceSupplier); //設置對象是單例模式還是多例模式,默認單例
   ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
   abd.setScope(scopeMetadata.getScopeName());    //獲取BeanName,設置的化就採用默認值,否則類名第一個字母小寫
   String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

   AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); //處理Lazy,primary等註解
   .....

   BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
   definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);//判斷對象是否需要代理,不需要直接返回,需要的化,重新創建BeanDefinition加入代理的信息
   BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);    //註冊配置類到IOC容器
}

3、調用shouldSkip()處理@Condition註解

public boolean shouldSkip(@Nullable AnnotatedTypeMetadata metadata, @Nullable ConfigurationPhase phase) {
   if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) { //如果沒有不是@Condition註解直接返回fasle
      return false;
   }
   if (phase == null) { //下面遞歸調用本方法
      if (metadata instanceof AnnotationMetadata &&
            ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) {
         return shouldSkip(metadata, ConfigurationPhase.PARSE_CONFIGURATION);
      }
      return shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN);
   }
   List<Condition> conditions = new ArrayList<>();
   for (String[] conditionClasses : getConditionClasses(metadata)) { //phase不爲空的時候,執行所有condition類的match方法。
      for (String conditionClass : conditionClasses) {
         Condition condition = getCondition(conditionClass, this.context.getClassLoader());
         conditions.add(condition);
      }
   }
    ....
   return false;
}

4、調用processCommonDefinitionAnnotations處理下面的的註解

static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
   AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
   if (lazy != null) {
      abd.setLazyInit(lazy.getBoolean("value"));
   }
   else if (abd.getMetadata() != metadata) {
      lazy = attributesFor(abd.getMetadata(), Lazy.class);
      if (lazy != null) {
         abd.setLazyInit(lazy.getBoolean("value"));
      }
   }
   if (metadata.isAnnotated(Primary.class.getName())) {
      abd.setPrimary(true);
   }
   AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
   if (dependsOn != null) {
      abd.setDependsOn(dependsOn.getStringArray("value"));
   }

   if (abd instanceof AbstractBeanDefinition) {
      AbstractBeanDefinition absBd = (AbstractBeanDefinition) abd;
      AnnotationAttributes role = attributesFor(metadata, Role.class);
      if (role != null) {
         absBd.setRole(role.getNumber("value").intValue());
      }
      AnnotationAttributes description = attributesFor(metadata, Description.class);
      if (description != null) {
         absBd.setDescription(description.getString("value"));
      }
   }
}

三、BeanFactory後置處理器 1、beanFactory後置處理器(以ConfigurationClassPostProcessor爲例)

1.1、ConfigurationClassPostProcessor繼承關係

1.2、接口說明

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
   void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
public interface BeanFactoryPostProcessor {
   void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

2、refresh()->invokeBeanFactoryPostProcessors方法執行beanFactory後置處理器

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
   if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }
}
public static void invokeBeanFactoryPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

   //2.1.1、執行IOC容器beanFactoryPostProcessors列表裏面存在的BeanDefinitionRegistryPostProcessor處理器
   //2.1.2、把實現了BeanDefinitionRegistryPostProcessor接口的對象放到registryPostProcessors列表
   //2.1.3、把只實現BeanFactoryPostProcessor接口的放到regularPostProcessors
   Set<String> processedBeans = new HashSet<>();

   if (beanFactory instanceof BeanDefinitionRegistry) {
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<>();
      List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
            new LinkedList<>();

      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
         if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
            BeanDefinitionRegistryPostProcessor registryPostProcessor =
                  (BeanDefinitionRegistryPostProcessor) postProcessor;
            registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
            registryPostProcessors.add(registryPostProcessor);
         }
         else {
            regularPostProcessors.add(postProcessor);
         }
      }
      //2.2、獲取所有註冊到IOC容器裏面的BeanDefinitionRegistryPostProcessor對象的beanName
      String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      //2.3、按照一定的順序執行postProcessBeanDefinitionRegistry方法,並且放到registryPostProcessors列表
      List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    ....

   else {
      invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
   }
    //2.4、獲取所有BeanFactoryPostProcessor對象並且執行postProcessBeanFactory方法
   String[] postProcessorNames =
         beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
  ....
}

3、ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry方法

@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
    ....
   processConfigBeanDefinitions(registry);
}
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
      //註冊BeanDefinitions
      this.reader.loadBeanDefinitions(configClasses);
      alreadyParsed.addAll(configClasses);
}

四、註冊Bean的後置處理器:registerBeanPostProcessors(beanFactory);

1、註冊bean後置處理器到IOC並且創建對象

public static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

....
    //根據實現的額接口不同,放入到不同的列表裏面
   List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
   List<String> orderedPostProcessorNames = new ArrayList<>();
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   for (String ppName : postProcessorNames) {
      if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
           //創建Bean
         BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
....

....
}

五、創建Bean對象

1、refresh()->finishBeanFactoryInitialization()->preInstantiateSingletons()

// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
 ....
   // Instantiate all remaining (non-lazy-init) singletons.
   beanFactory.preInstantiateSingletons();
}
@Override
public void preInstantiateSingletons() throws BeansException {
   if (this.logger.isDebugEnabled()) {
      this.logger.debug("Pre-instantiating singletons in " + this);
   }
   List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
   for (String beanName : beanNames) {
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);//是否創建對象
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         if (isFactoryBean(beanName)) {//是否是FactoryBean,是則調用getObject()方法
            final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
            boolean isEagerInit;
            if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
               isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) () ->
                     ((SmartFactoryBean<?>) factory).isEagerInit(),
                     getAccessControlContext());
            }
            else {
               isEagerInit = (factory instanceof SmartFactoryBean &&
                     ((SmartFactoryBean<?>) factory).isEagerInit());
            }
            if (isEagerInit) {
               getBean(beanName);
            }
         }
         else {
            getBean(beanName);
         }
      }
   }

2、getBean(beanName)方法核心步驟

@Override
public Object getBean(String name) throws BeansException {
   return doGetBean(name, null, null, false);
}

下面幾個關鍵的方法需要分析下getSingleton,createBean 和 getObjectForBeanInstance

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
      @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

   final String beanName = transformedBeanName(name);
   Object bean;

   // Eagerly check singleton cache for manually registered singletons.
   Object sharedInstance = getSingleton(beanName);
   if (sharedInstance != null && args == null) {
     ....
      bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);//從Bean的實例中獲取對象
   }

   else {
    ....
         // Create bean instance.
         if (mbd.isSingleton()) {
            sharedInstance = getSingleton(beanName, () -> {
               try {
                  return createBean(beanName, mbd, args);
               }
               catch (BeansException ex) {
                  // Explicitly remove instance from singleton cache: It might have been put there
                  // eagerly by the creation process, to allow for circular reference resolution.
                  // Also remove any beans that received a temporary reference to the bean.
                  destroySingleton(beanName);
                  throw ex;
               }
            });
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
         }

         else if (mbd.isPrototype()) {
            // It's a prototype -> create a new instance.
            Object prototypeInstance = null;
            try {
               beforePrototypeCreation(beanName);
               prototypeInstance = createBean(beanName, mbd, args);
            }
            finally {
               afterPrototypeCreation(beanName);
            }
            bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
         }

         else {
            String scopeName = mbd.getScope();
            final Scope scope = this.scopes.get(scopeName);
            if (scope == null) {
               throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
            }
            try {
               Object scopedInstance = scope.get(beanName, () -> {
                  beforePrototypeCreation(beanName);
                  try {
                     return createBean(beanName, mbd, args);
                  }
                  finally {
                     afterPrototypeCreation(beanName);
                  }
               });
               bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
            }
           ....
   }
....
   return (T) bean;
}

getSingleton方法執行流程【緩存中獲取單例bean】

bean的加載過程。單例bean在spring容器中只會被創建一次,後續再獲取Bean直接從單例緩存中獲取,當然這裏也只是嘗試加載,首先嚐試從緩存中加載,然後再次嘗試從singletonFactories中加載。

因爲在創建單例bean 的時候會存在依賴注入的情況,而在創建依賴的時候爲了避免循環依賴,spring創建bean的原則是不等bean創建完成就會將創建的bean的ObjectFactory提早曝光加入到緩存中,

一旦下一個bean創建時需要 依賴上一個Bean,則直接使用ObjectFactory。

public Object getSingleton(String beanName) {
   return getSingleton(beanName, true);//參數true設置標識允許早期依賴
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
   Object singletonObject = this.singletonObjects.get(beanName);//檢查緩存中是否存在實例
   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {//如果爲空
      synchronized (this.singletonObjects) {//如果爲空,則鎖定全局變量進行處理
         singletonObject = this.earlySingletonObjects.get(beanName);//如果此bean正在加載,則不會處理後面邏輯
         if (singletonObject == null && allowEarlyReference) {//當某些方法需要提前初始化的時候
            ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
            if (singletonFactory != null) {
               singletonObject = singletonFactory.getObject();//調用預先設定的getObject方法,創建bean
               this.earlySingletonObjects.put(beanName, singletonObject);//記錄在緩存中earlySingletonObjects和singletonFactories互斥
               this.singletonFactories.remove(beanName);
            }
         }
      }
   }
   return singletonObject;
}
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);

  • singletonObjects:用於保存BeanName和創建Bean實例之間的關係,bean name->bean instance
  • singletonFactories:用於保存BeanName和創建bean工廠之間的關係,bean name->ObjectFactory
  • earlySingletonObjects:也是保存BeanName和創建Bean實例之間的關係,與singletonObjects不同在於,當一個單例bean被放到這裏面後,那麼當bean還在創建過程中,就可以通過getBean方法獲取到了,其目的是爲了檢測循環引用。
  • registeredSingletons:用來保存當前所有已註冊的Bean

getObjectForBeanInstance方法執行流程

在getBean方法中,getObjectForBeanInstance是個高頻率使用的方法,無論是從緩存中獲取bean還是根據不同的scope策略加載bean。總之我們得到Bean的實例後要做的第一步就是調用這個方法來檢測當前Bean是否是FactoryBean類型

如果是,那麼需要調用該Bean對應 的FactoryBean實例中的getObject()作爲返回值。

無論是從緩存中獲取到Bean還是通過不同的scope策略加載的Bean都只是最原始的Bean狀態,並不一定是我們想要的Bean。

舉個例子:假如我們需要對工廠Bean進行處理,那麼這裏得到的是工廠Bean的初始狀態,但是我們正真需要的是工廠Bean中定義的factory-method方法中返回的Bean,而getObjectForBeanInstance方法就是完成這個工作的。

下面來分析下getObjectForBeanInstance這個方法:

protected Object getObjectForBeanInstance(
      Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

   // 如果指定的name是工廠相關(以&爲前綴)且BeanInstance又不是FactoryBean類型則驗證不通過
   if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
      throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
   }

   // 現在我們有了這個Bean實例,這個實例可能會是正常的Bean或者FactoryBean
   // 如果是FactoryBean我們使用它創建實例,但是如果用戶想要直接獲取工廠實例而不是工廠的getObject方法對應的實例,那麼傳入的name應該加入前綴&
   if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
      return beanInstance;
   }
   //加載FactoryBean
   Object object = null;
   if (mbd == null) {
      //嘗試從緩存中加載Bean
      object = getCachedObjectForFactoryBean(beanName);
   }
   if (object == null) {
      // 到這塊已經明確了beanInstance一定是FactoryBean類型
      FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
      // Caches object obtained from FactoryBean if it is a singleton.
      if (mbd == null && containsBeanDefinition(beanName)) {
         mbd = getMergedLocalBeanDefinition(beanName);
      }
      //是否是用戶定義的而不是應用程序本身定義的
      boolean synthetic = (mbd != null && mbd.isSynthetic());
      object = getObjectFromFactoryBean(factory, beanName, !synthetic);
   }
   return object;
}

從上面代碼來看,大多是些輔助代碼以及一些功能性的判斷,而正真的核心委託給getObjectFromFactoryBean,我們來看看這個方法:

這個方法裏面只做了一件事情,就是返回的Bean如果是單例,那麼就必須要保證全局唯一,同時也因爲是單例的,所以不必重複創建,可以使用緩存來提高性能,

也就是說,以及加載過就要記錄下來以便於下次複用,否則的化就直接獲取了。

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
   if (factory.isSingleton() && containsSingleton(beanName)) {//如果是單例模式
      synchronized (getSingletonMutex()) {//鎖住全局變量
         Object object = this.factoryBeanObjectCache.get(beanName);
         if (object == null) {
            object = doGetObjectFromFactoryBean(factory, beanName);
           //緩存中獲取bean
            Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
            if (alreadyThere != null) {
               object = alreadyThere;
            }
            else {
               if (shouldPostProcess) {
                  try {
                     object = postProcessObjectFromFactoryBean(object, beanName);
                  }
                  catch (Throwable ex) {
                     throw new BeanCreationException(beanName,
                           "Post-processing of FactoryBean's singleton object failed", ex);
                  }
               }
               this.factoryBeanObjectCache.put(beanName, object);
            }
         }
         return object;
      }
   }
   else {
      Object object = doGetObjectFromFactoryBean(factory, beanName);//執行這個方法,會去調用getObject方法
      if (shouldPostProcess) {
         try {
            object = postProcessObjectFromFactoryBean(object, beanName);//調用ObjectFactory的後處理器
         }
         catch (Throwable ex) {
            throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
         }
      }
      return object;
   }
}

下面看下:doGetObjectFromFactoryBean方法:

private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
      throws BeanCreationException {

   Object object;
   try {
      if (System.getSecurityManager() != null) {//需要權限驗證
         AccessControlContext acc = getAccessControlContext();
         try {
            object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
                  factory.getObject(), acc);
         }
         catch (PrivilegedActionException pae) {
            throw pae.getException();
         }
      }
      else {
         object = factory.getObject();//直接調用getObject方法
      }
   }
...
   return object;
}

上面我們已經講述了FactoryBean的調用方法,如果Bean聲明爲FactoryBean類型,則當提取Bean的時候取到的並不是FactoryBean而是FactoryBean中對應的getObject方法返回的Bean,

doGetObjectFromFactoryBean正是實現了這個功能的。但是我們看到了上面的方法中除了調用object = factory.getObject()得到我們想要的結果後並沒有直接返回,而是接下來又調用

postProcessObjectFromFactoryBean來做後置處理,我們進入這個後置處理方法,看看:

protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
   return applyBeanPostProcessorsAfterInitialization(object, beanName);
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
      throws BeansException {

   Object result = existingBean;
   for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
      Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
      if (current == null) {
         return result;
      }
      result = current;
   }
   return result;
}

對於後置處理器的使用,後續會講解到,這裏我們需要明確一點:在Spring中獲取Bean的規則中有一條:儘可能保證所有的Bean初始化後都會調用註冊的

BeanPostProcessor的postProcessAfterInitialization方法進行處理,在實際開發中大可以爭對此特性設計自己的業務邏輯。

獲取單例:

// Create bean instance.
if (mbd.isSingleton()) {
   sharedInstance = getSingleton(beanName, () -> {
      try {
         return createBean(beanName, mbd, args);
      }
      catch (BeansException ex) {
         // Explicitly remove instance from singleton cache: It might have been put there
         // eagerly by the creation process, to allow for circular reference resolution.
         // Also remove any beans that received a temporary reference to the bean.
         destroySingleton(beanName);
         throw ex;
      }
   });
   bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

如果緩存不存在已經加載的單例Bean,就需要從頭開始Bean的加載過程,而Spring中使用了getSingleton的重載方法實現Bean的加載過程
進入getSingleton方法

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
   Assert.notNull(beanName, "Bean name must not be null");
   synchronized (this.singletonObjects) {
      Object singletonObject = this.singletonObjects.get(beanName);
      if (singletonObject == null) {
         if (this.singletonsCurrentlyInDestruction) {
            throw new BeanCreationNotAllowedException(beanName,
                  "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                  "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
         }
         if (logger.isDebugEnabled()) {
            logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
         }
         beforeSingletonCreation(beanName);
         boolean newSingleton = false;
         boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
         if (recordSuppressedExceptions) {
            this.suppressedExceptions = new LinkedHashSet<>();
         }
         try {
            singletonObject = singletonFactory.getObject();
            newSingleton = true;
         }
         catch (IllegalStateException ex) {
            // Has the singleton object implicitly appeared in the meantime ->
            // if yes, proceed with it since the exception indicates that state.
            singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
               throw ex;
            }
         }
         catch (BeanCreationException ex) {
            if (recordSuppressedExceptions) {
               for (Exception suppressedException : this.suppressedExceptions) {
                  ex.addRelatedCause(suppressedException);
               }
            }
            throw ex;
         }
         finally {
            if (recordSuppressedExceptions) {
               this.suppressedExceptions = null;
            }
            afterSingletonCreation(beanName);
         }
         if (newSingleton) {
            addSingleton(beanName, singletonObject);
         }
      }
      return singletonObject;
   }
}
protected void beforeSingletonCreation(String beanName) {
   if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {//將當前需要創建的Bean記錄在緩存中,這樣可以對循環依賴進行檢測
      throw new BeanCurrentlyInCreationException(beanName);
   }
}
protected void afterSingletonCreation(String beanName) {
   if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {//當Bean加載結束後需要移除緩存中對該Bean的正在加載狀態的記錄
      throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
   }
}

返回處理結果

雖然我們已經從外部瞭解到了加載Bean的邏輯架構,但現在我們還並沒有開始對Bean加載功能的探索,之前提到過,Bean的加載邏輯其實是在傳入的ObjectFactory類型的參數singletonFactory中定義的,

我們反推參數的獲取,得到如下的代碼:

sharedInstance = getSingleton(beanName,new ObjectFactory<Object>() {
      public Object getObject() throws BeansException{
        try{
             return createBean(beanName, mbd, args);
        }catch(BeansException ex){
            destroySingleton(beanName);
            throw ex;
        }
      }
})

ObjectFactory的核心部分其實只是調用了createBean的方法,所以我們還需要到createBean方法中尋找真理!

準備創建Bean [createBean方法執行流程]

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {
....
   try {
      Object beanInstance = doCreateBean(beanName, mbdToUse, args);
      if (logger.isDebugEnabled()) {
         logger.debug("Finished creating instance of bean '" + beanName + "'");
      }
      return beanInstance;
....
}
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
      throws BeanCreationException {

....
   try {
      populateBean(beanName, mbd, instanceWrapper);
      exposedObject = initializeBean(beanName, exposedObject, mbd);
   }
  .....
}
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         invokeAwareMethods(beanName, bean);
         return null;
      }, getAccessControlContext());
   }
   else {
      invokeAwareMethods(beanName, bean);//執行aware接口相關方法
   }

   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);//Bean後置處理器的前置方法
   }

   try {
      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()) {
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);//Bean後置處理器的後置方法
   }

   return wrappedBean;
}

此方法中最吸引我們的無疑是兩個方法:applyBeanPostProcessorsBeforeInitialization以及applyBeanPostProcessorsAfterInitialization。這兩個方法是實現非常簡單,

無非是對後處理器中的所有 InstantiationAwareBeanPostProcessor類型的後置處理器BeanPostProcessor進行postProcessBeforeInitialization方法和postProcessAfterInitialization方法的調用

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
      throws BeansException {

   Object result = existingBean;
   for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
      Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
      if (current == null) {
         return result;
      }
      result = current;
   }
   return result;
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
      throws BeansException {

   Object result = existingBean;
   for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
      Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
      if (current == null) {
         return result;
      }
      result = current;
   }
   return result;
}

根據上面代碼可知:Bean的實例化前調用,也就是將AbstractBeanDefinition轉換爲BeanWrapper前的處理。給子類一個修改BeanDefinition的機會,也就是說當程序經過這個方法後,

Bean可能已經不是我們認爲的Bean了,而是經過代理後的Bean,可能是CGLIB生成的,也可能是通過其它技術生成的。後面會分析到。

到這裏,結束創建單例的對象

SpringBean的生命週期總結

源碼分析流程:

1、執行refresh()刷新方法

2、finishBeanFactoryInitialization(beanFactory);

3、beanFactory.preInstantiateSingletons();

4、getBean(beanName)->doGetBean()->createBean()->doCreateBean()->createBeanInstance()初始化對象(默認情況下使用Java反射機制初始化對象,也可以通過CGLIB)

5、initializeBean()

6、invokeAwareMethods()判斷是否有Aware接口依賴信息

7、applyBeanPostProcessorsBeforeInitialization()執行前置處理

8、invokeInitMethods()執行init()方法

8、applyBeanPostProcessorsAfterInitialization()執行後置處理

本文參考:

書籍:Spring源碼深度解析

螞蟻課堂:http://www.mayikt.com/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章