首頁>技術>

1.1 Spring測試環境搭建

Spring模組概覽,綠色是模組,Spring中八大模組,黑色表示該模組包含的jar包(元件)。例如我們想要用IOC容器,也就是綠色的CoreContainer,我們需要匯入Beans,Core,Context,SpEL(spring-expression)四個包。

Spring模組概覽

Test:測試相關Core Container:IOC容器AOP:面向切面程式設計Aspects:切面Instrumenttation:跟JDK關聯,一般不用Messaging:訊息服務,一般不用Data Access/Integration:資料訪問與整合(JDBC訪問,Transaction事務,ORM物件關係對映,OXM和XML對映一般不用,JMS為Java訊息服務Java-message-service一般不用)Web:Web服務(WebSocket網路通訊協議,Servlet, Web,Portlet一般不用)

最偷懶的方式,是直接匯入Spring-Framework。但是可能匯入不必要的包,導致專案打包後比較大

由於Spring-Content中的ApplicationContent是整個IOC的入口。我們匯入Spring-context包即可

  <dependencies>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-aop</artifactId>      <version>5.2.3.RELEASE</version>      <scope>compile</scope>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-beans</artifactId>      <version>5.2.3.RELEASE</version>      <scope>compile</scope>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-core</artifactId>      <version>5.2.3.RELEASE</version>      <scope>compile</scope>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-expression</artifactId>      <version>5.2.3.RELEASE</version>      <scope>compile</scope>    </dependency>  </dependencies>

新建Spring配置檔案spring.xml:

import com.xiaodai.service.Hello;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {    public static void main(String[] args) {        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");        Hello hello = applicationContext.getBean("hello", Hello.class);        System.out.println(hello.getName());    }}
1.2 Debug容器建立過程

從測試類的new ClassPathXmlApplicationContext("spring.xml")開始debug,進入ClassPathXmlApplicationContext,可以看到:

 public ClassPathXmlApplicationContext(   String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)   throws BeansException {  super(parent);  // 設定配置檔案路徑  setConfigLocations(configLocations);  if (refresh) {          // 核心步驟   refresh();  } }

載入配置檔案後,進入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.   /**     * 獲得一個重新整理的bean容器,實質就是獲取工廠。    * 載入xml等配置檔案,用該檔案產生的BeanDefinition來建立一個工廠   **/   ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();   // Prepare the bean factory for use in this context.   /**    * 準備bean工廠   **/   prepareBeanFactory(beanFactory);   try {    // Allows post-processing of the bean factory in context subclasses.    // 後置增強,方便擴充套件    postProcessBeanFactory(beanFactory);    // Invoke factory processors registered as beans in the context.    // 例項化並且執行BeanFactoryPostProcessors    invokeBeanFactoryPostProcessors(beanFactory);    // Register bean processors that intercept bean creation.    // 例項化並且註冊所有的BeanPostProcessor    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();   }  } }
1.3 AbstractApplicationContext的refresh()包含的13個方法分析

結合概覽圖一個一個方法分析:

Bean工廠例項化Bean概覽圖

方法1:prepareRefresh() => 準備工作

準備重新整理,做一些最基本的準備化工作

 protected void prepareRefresh() {  // Switch to active.  // 設定開始時間  this.startupDate = System.currentTimeMillis();  // 關閉狀態設定為false  this.closed.set(false);  // 活躍狀態設定為true  this.active.set(true);        // 列印日誌  if (logger.isDebugEnabled()) {   if (logger.isTraceEnabled()) {    logger.trace("Refreshing " + this);   }   else {    logger.debug("Refreshing " + getDisplayName());   }  }  // Initialize any placeholder property sources in the context environment.  // 初始化屬性資源  initPropertySources();  // Validate that all properties marked as required are resolvable:  // see ConfigurablePropertyResolver#setRequiredProperties  // 獲取環境資訊,驗證屬性資訊  getEnvironment().validateRequiredProperties();  // Store pre-refresh  // 儲存預重新整理的一些應用資訊的監聽器  ApplicationListeners...  if (this.earlyApplicationListeners == null) {   this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);  }  else {   // Reset local application listeners to pre-refresh state.   this.applicationListeners.clear();   this.applicationListeners.addAll(this.earlyApplicationListeners);  }  // Allow for the collection of early ApplicationEvents,  // to be published once the multicaster is available...  // 建立一些監聽器事件的集合  this.earlyApplicationEvents = new LinkedHashSet<>(); }

總結:1.設定啟動事件 2.設定關閉活躍的狀態 3.獲取環境物件並設定屬性值 4.設定監聽器以及需要釋出事件的集合。

重要的點:

獲取環境資訊,驗證屬性資訊,getEnvironment().validateRequiredProperties();儲存預重新整理的一些應用資訊的監聽器,在Spring中是空實現,但是SpringBoot中,是有具體的值的方法2:obtainFreshBeanFactory() => 獲得一個重新整理的bean容器

獲得一個重新整理的bean容器,實質就是獲取工廠。建立容器物件DefaultListableBeanFactory;載入xml配置檔案的屬性到當前的工廠中,最重要的就是BeanDefinition

Bean工廠例項繼承關係圖

AbstractRefreshableApplicationContext:

    // 只要進到這個方法,那麼我們建立的一定是一個新的工廠 @Override protected final void refreshBeanFactory() throws BeansException {  if (hasBeanFactory()) {      // 如果存在先銷燬,後關閉   destroyBeans();   closeBeanFactory();  }  try {      // 建立bean工廠,這裡使用的就是DefaultListableBeanFactory。此時建立的工廠裡面的屬性值都是預設值   DefaultListableBeanFactory beanFactory = createBeanFactory();   // 序列化id   beanFactory.setSerializationId(getId());   // 設定一些屬性值   customizeBeanFactory(beanFactory);   // 載入bean的定義屬性值。該方法有很多過載,非常複雜,核心是do操作   // 完成配置檔案或者配置類檔案的載入   loadBeanDefinitions(beanFactory);   synchronized (this.beanFactoryMonitor) {    this.beanFactory = beanFactory;   }  }  catch (IOException ex) {   throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);  } }
方法3:prepareBeanFactory(beanFactory) => 準備(初始化)Bean工廠

為方法2拿到的工廠,設定某些具體的值

 protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {  // Tell the internal bean factory to use the context's class loader etc.  // 為bean工廠設定類載入器  beanFactory.setBeanClassLoader(getClassLoader());  // 設定SPEL解析器  beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));  beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));  // Configure the bean factory with context callbacks.  // 新增一個BeanPostProcessor  beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));  // 忽略對應介面的實現  beanFactory.ignoreDependencyInterface(EnvironmentAware.class);  beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);  beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);  beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);  beanFactory.ignoreDependencyInterface(MessageSourceAware.class);  beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);  // BeanFactory interface not registered as resolvable type in a plain factory.  // MessageSource registered (and found for autowiring) as a bean.        // 註冊一些依賴  beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);  beanFactory.registerResolvableDependency(ResourceLoader.class, this);  beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);  beanFactory.registerResolvableDependency(ApplicationContext.class, this);  // Register early post-processor for detecting inner beans as  // ApplicationListeners新增一個BeanPostProcessor增強器  ApplicationListeners.  beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));  // Detect a LoadTimeWeaver and prepare for weaving, if found.  if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {   beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));   // Set a temporary ClassLoader for type matching.   beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));  }  // Register default environment beans.  if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {   beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());  }  if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {   beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());  }  if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {   beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());  } }
方法4:postProcessBeanFactory(beanFactory) => 後置增強Bean(擴充套件實現)

空方法,方便擴充套件

方法5:invokeBeanFactoryPostProcessors(beanFactory) => 執行BFPP

例項化並且執行BeanFactoryPostProcessors

 /**  * Instantiate and invoke all registered BeanFactoryPostProcessor beans,  * respecting explicit order if given.  * <p>Must be called before singleton instantiation.  * 單例物件之前一定呼叫,因為單例bean建立後就只有一份  */ protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {  PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());  // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime  // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)  if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {   beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));   beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));  } }
方法6:registerBeanPostProcessors(beanFactory) => 註冊BPP

例項化並且註冊所有的BeanPostProcessor。例項化Bean之前的準備工作

 /**  * Instantiate and register all BeanPostProcessor beans,  * respecting explicit order if given.  * <p>Must be called before any instantiation of application beans.  */ protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {  PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); }
方法7:initMessageSource() => 國際化設定方法8:initApplicationEventMulticaster() => 初始化應用程式的多波器和廣播器

也屬於準備工作

方法9:onRefresh() => 預留給子類做擴充套件

空方法

方法10:registerListeners() => 註冊監聽器

也屬於準備工作

 /**  * Add beans that implement ApplicationListener as listeners.  * Doesn't affect other listeners, which can be added without being beans.  */ protected void registerListeners() {  // Register statically specified listeners first.  for (ApplicationListener<?> listener : getApplicationListeners()) {   getApplicationEventMulticaster().addApplicationListener(listener);  }  // Do not initialize FactoryBeans here: We need to leave all regular beans  // uninitialized to let post-processors apply to them!  String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);  for (String listenerBeanName : listenerBeanNames) {   getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);  }  // Publish early application events now that we finally have a multicaster...  Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;  this.earlyApplicationEvents = null;  if (earlyEventsToProcess != null) {   for (ApplicationEvent earlyEvent : earlyEventsToProcess) {    getApplicationEventMulticaster().multicastEvent(earlyEvent);   }  } }
方法11:finishBeanFactoryInitialization(beanFactory) => 例項化所有單例物件

面試常問,工作常用。過程比較複雜

 /**  * Finish the initialization of this context's bean factory,  * initializing all remaining singleton beans.  */ protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {  // Initialize conversion service for this context.  /**   * 把型別轉化操作,設定到當前的beanFactory裡面去  **/  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.  /**   * 判斷當前的beanFactory有沒有內建的值處理器  **/  if (!beanFactory.hasEmbeddedValueResolver()) {   beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));  }  // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.  /**   * 織入Aware  **/  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.  /**   * 凍結:某些bean不需要進行修改操作了,放入  **/  beanFactory.freezeConfiguration();  // Instantiate all remaining (non-lazy-init) singletons.  /**   * 例項化所有非懶載入的例項物件(重要)  **/  beanFactory.preInstantiateSingletons(); }

例項化所有非懶載入的例項物件方法:

 @Override public void preInstantiateSingletons() throws BeansException {  if (logger.isTraceEnabled()) {   logger.trace("Pre-instantiating singletons in " + this);  }  // Iterate over a copy to allow for init methods which in turn register new bean definitions.  // While this may not be part of the regular factory bootstrap, it does otherwise work fine.  /**   * 拿到所有註冊bean的名稱   **/  List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);  // Trigger initialization of all non-lazy singleton beans...  // 迴圈去建立我們需要的單例物件  for (String beanName : beanNames) {      // 拿到bean的定義資訊,就是我們在xml配置檔案裡面指定的一些屬性   RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);   // 是否是抽象的,是否是單例的,是否是懶載入的   if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {       // 判斷當前類是否實現了factoryBean介面。一般沒實現,直接進入下面的getBean    if (isFactoryBean(beanName)) {     Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);     if (bean instanceof FactoryBean) {      final FactoryBean<?> factory = (FactoryBean<?>) bean;      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 {        // 透過beanName。拿到bean     getBean(beanName);    }   }  }  // Trigger post-initialization callback for all applicable beans...  for (String beanName : beanNames) {   Object singletonInstance = getSingleton(beanName);   if (singletonInstance instanceof SmartInitializingSingleton) {    final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;    if (System.getSecurityManager() != null) {     AccessController.doPrivileged((PrivilegedAction<Object>) () -> {      smartSingleton.afterSingletonsInstantiated();      return null;     }, getAccessControlContext());    }    else {     smartSingleton.afterSingletonsInstantiated();    }   }  } }

重要方法:

createBeanInstance => 核心的建立和例項化bean的過程,由doCreateBean呼叫

大量的反射出現在該方法中,用來建立物件

 /**  * Create a new instance for the specified bean, using an appropriate instantiation strategy:  * factory method, constructor autowiring, or simple instantiation.  * @param beanName the name of the bean  * @param mbd the bean definition for the bean  * @param args explicit arguments to use for constructor or factory method invocation  * @return a BeanWrapper for the new instance  * @see #obtainFromSupplier  * @see #instantiateUsingFactoryMethod  * @see #autowireConstructor  * @see #instantiateBean  */ 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); }
instantiateBean(beanName, mbd) => 預設無參構造
 /**  * Instantiate the given bean using its default constructor.  * @param beanName the name of the bean  * @param mbd the bean definition for the bean  * @return a BeanWrapper for the new instance  */ protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {  try {   Object beanInstance;   final BeanFactory parent = this;   if (System.getSecurityManager() != null) {    beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->            // 例項化只會分配記憶體空間,設定預設值      getInstantiationStrategy().instantiate(mbd, beanName, parent),      getAccessControlContext());   }   else {    beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);   }   BeanWrapper bw = new BeanWrapperImpl(beanInstance);   initBeanWrapper(bw);   return bw;  }  catch (Throwable ex) {   throw new BeanCreationException(     mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);  } }
instantiate
 @Override public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {  // Don't override the class with CGLIB if no overrides.  if (!bd.hasMethodOverrides()) {   Constructor<?> constructorToUse;   synchronized (bd.constructorArgumentLock) {    constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;    if (constructorToUse == null) {     final Class<?> clazz = bd.getBeanClass();     if (clazz.isInterface()) {      throw new BeanInstantiationException(clazz, "Specified class is an interface");     }     try {      if (System.getSecurityManager() != null) {       constructorToUse = AccessController.doPrivileged(         (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);      }      else {       constructorToUse = clazz.getDeclaredConstructor();      }      bd.resolvedConstructorOrFactoryMethod = constructorToUse;     }     catch (Throwable ex) {      throw new BeanInstantiationException(clazz, "No default constructor found", ex);     }    }   }   return BeanUtils.instantiateClass(constructorToUse);  }  else {   // Must generate CGLIB subclass.   return instantiateWithMethodInjection(bd, beanName, owner);  } }
BeanUtils.instantiateClass => 透過構造器反射建立bean
 /**  * Convenience method to instantiate a class using the given constructor.  * <p>Note that this method tries to set the constructor accessible if given a  * non-accessible (that is, non-public) constructor, and supports Kotlin classes  * with optional parameters and default values.  * @param ctor the constructor to instantiate  * @param args the constructor arguments to apply (use {@code null} for an unspecified  * parameter, Kotlin optional parameters and Java primitive types are supported)  * @return the new instance  * @throws BeanInstantiationException if the bean cannot be instantiated  * @see Constructor#newInstance  */ public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {  Assert.notNull(ctor, "Constructor must not be null");  try {   ReflectionUtils.makeAccessible(ctor);   if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {    return KotlinDelegate.instantiateClass(ctor, args);   }   else {    Class<?>[] parameterTypes = ctor.getParameterTypes();    Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");    Object[] argsWithDefaultValues = new Object[args.length];    for (int i = 0 ; i < args.length; i++) {     if (args[i] == null) {      Class<?> parameterType = parameterTypes[i];      argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);     }     else {      argsWithDefaultValues[i] = args[i];     }    }    return ctor.newInstance(argsWithDefaultValues);   }  }  catch (InstantiationException ex) {   throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);  }  catch (IllegalAccessException ex) {   throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);  }  catch (IllegalArgumentException ex) {   throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);  }  catch (InvocationTargetException ex) {   throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());  } }
方法12:finishRefresh() => 完成重新整理
 /**  * Finish the refresh of this context, invoking the LifecycleProcessor's  * onRefresh() method and publishing the  * {@link org.springframework.context.event.ContextRefreshedEvent}.  */ protected void finishRefresh() {  // Clear context-level resource caches (such as ASM metadata from scanning).  //   clearResourceCaches();  // Initialize lifecycle processor for this context.  initLifecycleProcessor();  // Propagate refresh to lifecycle processor first.  getLifecycleProcessor().onRefresh();  // Publish the final event.  publishEvent(new ContextRefreshedEvent(this));  // Participate in LiveBeansView MBean, if active.  LiveBeansView.registerApplicationContext(this); }
方法13:resetCommonCaches() => 快取重置
 /**  * Reset Spring's common reflection metadata caches, in particular the  * {@link ReflectionUtils}, {@link AnnotationUtils}, {@link ResolvableType}  * and {@link CachedIntrospectionResults} caches.  * @since 4.2  * @see ReflectionUtils#clearCache()  * @see AnnotationUtils#clearCache()  * @see ResolvableType#clearCache()  * @see CachedIntrospectionResults#clearClassLoader(ClassLoader)  */ protected void resetCommonCaches() {  ReflectionUtils.clearCache();  AnnotationUtils.clearCache();  ResolvableType.clearCache();  CachedIntrospectionResults.clearClassLoader(getClassLoader()); }

最後回顧整個流程概覽圖:

4
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Java原始碼——JDK1.8HashMap 重點原始碼部分剖析