Spring 核心流程

Spring 核心流程

  • 前言
  • 一、AbstractApplicationContext#refresh 方法解析
    • 1.1 前置
    • 1.2 refresh 方法
      • 1.2.1 prepareRefresh
      • 1.2.2 obtainFreshBeanFactory
      • 1.2.3 prepareBeanFactory
      • 1.2.4 postProcessBeanFactory
      • 1.2.5 invokeBeanFactoryPostProcessors
      • 1.2.6 registerBeanPostProcessors
      • 1.2.7 initApplicationEventMulticaster
      • 1.2.8 onRefresh
      • 1.2.9 registerListeners
      • 1.2.10 finishBeanFactoryInitialization
      • 1.2.11 finishRefresh
    • 1.3 Bean 的生命周期
      • 1.3.1 入口
      • 1.3.2 preInstantiateSingletons
      • 1.3.3 doGetBean
      • 1.3.4 createBean
      • 1.3.5 doCreateBean
      • 1.3.6 populateBean
      • 1.3.7 initializeBean 初始化 bean
  • 二、各種 BeanPostProcessor(BPP)
    • InstantiationAwareBeanPostProcessor
    • MergedBeanDefinitionPostProcessor
    • SmartInstantiationAwareBeanPostProcessor
    • DestructionAwareBeanPostProcessor
  • 總結
    • Bean 的生命周期


前言

基于源碼 springboot2.7.3,對應 spring5.3.22
本章源碼只注釋 AbstractApplicationContext#refresh 方法


一、AbstractApplicationContext#refresh 方法解析

1.1 前置

Spring 的大致流程是先將 Bean 讀取成 BeanDefinition,然后再實例化 bean,初始化Bean
無論是使用注解還是 XML 配置的方式,都會將 Bean 解析成 BeanDefinition, XML解析的核心類是 XmlBeanDefinitionReader

1.2 refresh 方法

模板方法,里面大量的擴展點可交由子類實現

// 刷新前的操作prepareRefresh();// Tell the subclass to refresh the internal bean factory.// 獲取 BeanFactoryConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context.// 預處理 beanFactory// 向 beanFactory 添加了一些 ignoreDependencyInterfaceprepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.// 交由子類實現, 在刷新前對 beanFactory 做一些操作postProcessBeanFactory(beanFactory);StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");// Invoke factory processors registered as beans in the context.// 執行 BFPPinvokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.// 注冊 BPPregisterBeanPostProcessors(beanFactory);beanPostProcess.end();// Initialize message source for this context.// 初始化 MessageSource, i18n 相關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.// 重要, 完成 bean 的初始化工作finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.// 結束刷新finishRefresh();

1.2.1 prepareRefresh

protected void prepareRefresh() {// Switch to active.this.startupDate = System.currentTimeMillis();this.closed.set(false);this.active.set(true);// ... 日志打印// Initialize any placeholder property sources in the context environment.// 初始化 PropertySources, 如果是 servlet 應用的話, 會將 ServletContext 的配置信息放入到 Environment 中initPropertySources();// Validate that all properties marked as required are resolvable:// see ConfigurablePropertyResolver#setRequiredProperties// 如果有必須的配置, 驗證配置是否存在getEnvironment().validateRequiredProperties();// Store pre-refresh ApplicationListeners...// earlyApplicationListeners:提前暴露的 Listener// 兼容 SpringBootif (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.2 obtainFreshBeanFactory

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {// 刷新 beanFactory// 交由子類實現的方法// 1. 如果是 Spring 應用, 則是 AbstractRefreshableApplicationContext, 會創建 beanFactory// 2. 如果是 SpringBoot 應用, 實現類則是 GenericApplicationContext, beanFactory 已經提前創建好了, 直接獲取出來refreshBeanFactory();return getBeanFactory();
}

1.2.3 prepareBeanFactory

對 BeanFactory 做一些前置處理

// 1. ignoreDependencyInterface
// 2. registerResolvableDependency
// 3. 將 environment、System、ApplicationSetup 等 Bean 加入到 beaFactory
// 4. 將 ApplicationContext(this) 注冊到 BeanFactory

1.2.4 postProcessBeanFactory

鉤子, 交給子類實現,這里看 SpringBoot 的實現

@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {// 添加了一個 BPPbeanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));beanFactory.ignoreDependencyInterface(ServletContextAware.class);// 將 Request 和 Session 兩個 Scope 注冊到 ApplicationContextregisterWebApplicationScopes();
}

1.2.5 invokeBeanFactoryPostProcessors

執行 BFPP

  1. BFPP 主要分為兩種,一種是 BeanDefinitionRegistryPostProcessor,這個類可以用來注冊 BeanDefinition,而新注冊的 BeanDefinition 也可能是一個 BeanDefinitionRegistryPostProcessor,另外一種就只是 BFPP
  2. BFPP 的優先級 使用 applicationContext 直接注冊的 > @PriorityOrder > @Order > 普通的
public static void invokeBeanFactoryPostProcessors(  ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPos tProcessor> beanFactoryPostProcessors) {  // beanFactory 一般是 DefaultListableBeanFactory, 它確實是一個 BeanDefinitionRegistryif (beanFactory instanceof BeanDefinitionRegistry) {  BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; // 常規的 BFPP List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); // 能夠注冊 bean 的 BFPPList<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();  for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {  if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {  BeanDefinitionRegistryPostProcessor registryProcessor =  (BeanDefinitionRegistryPostProcessor) postProcessor;  // 調用 postProcessBeanDefinitionRegistry,注冊 beanregistryProcessor.postProcessBeanDefinitionRegistry(registry);  registryProcessors.add(registryProcessor);  }  else {  regularPostProcessors.add(postProcessor);  }  }  // 從容器中獲取所有的 BeanDefinitionRegistryPostProcessorString[] postProcessorNames =  beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);  for (String ppName : postProcessorNames) {  if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {  currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));  processedBeans.add(ppName);  }  }  sortPostProcessors(currentRegistryProcessors, beanFactory);  registryProcessors.addAll(currentRegistryProcessors);  invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());  currentRegistryProcessors.clear();  // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.  postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);  for (String ppName : postProcessorNames) {  if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {  currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));  processedBeans.add(ppName);  }  }  sortPostProcessors(currentRegistryProcessors, beanFactory);  registryProcessors.addAll(currentRegistryProcessors);  invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());  currentRegistryProcessors.clear();  // 這里為什么要用 while? 因為 BeanDefinitionRegistryPostProcessor 還有可能注冊 BeanDefinitionRegistryPostProcessorsboolean reiterate = true;  while (reiterate) {  reiterate = false;  postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);  for (String ppName : postProcessorNames) {  if (!processedBeans.contains(ppName)) {  currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));  processedBeans.add(ppName);  reiterate = true;  }  }  sortPostProcessors(currentRegistryProcessors, beanFactory);  registryProcessors.addAll(currentRegistryProcessors);  invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());  currentRegistryProcessors.clear();  }  // Now, invoke the postProcessBeanFactory callback of all processors handled so far.  // 執行 register 的 postProcessorinvokeBeanFactoryPostProcessors(registryProcessors, beanFactory);  // 然后執行參數中傳過來的 bfpp 的 postProcessor// 注意:這里只處理參數傳過來的 BFPPinvokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);  }  else {  // Invoke factory processors registered with the context instance.  invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);  }  // 下面將會執行容器中所有的 BFPPbeanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);  // 1. 標注了 @PriorityOrdered 的 BFPPList<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();  // 2. 標注了 @Order 的 BFPPList<String> orderedPostProcessorNames = new ArrayList<>();  // 3. 普通的 BFPPList<String> nonOrderedPostProcessorNames = new ArrayList<>();  for (String ppName : postProcessorNames) {  if (processedBeans.contains(ppName)) {  // skip - already processed in first phase above  }  else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {  priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));  }  else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {  orderedPostProcessorNames.add(ppName);  }  else {  nonOrderedPostProcessorNames.add(ppName);  }  }  // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.  sortPostProcessors(priorityOrderedPostProcessors, beanFactory);  invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);  // Next, invoke the BeanFactoryPostProcessors that implement Ordered.  List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());  for (String postProcessorName : orderedPostProcessorNames) {  orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));  }  sortPostProcessors(orderedPostProcessors, beanFactory);  invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);  // Finally, invoke all other BeanFactoryPostProcessors.  List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());  for (String postProcessorName : nonOrderedPostProcessorNames) {  nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));  }  invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);  // Clear cached merged bean definitions since the post-processors might have  // modified the original metadata, e.g. replacing placeholders in values...    beanFactory.clearMetadataCache();  
}

1.2.6 registerBeanPostProcessors

注冊 BPP
優先級 @PriorityOrdered > Ordered > 普通的

public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {// 獲取所有的 BPPString[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);// BPP的數量,這里 +1 是因為下面要加一個int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));// 1. PriorityOrdered 的 BPPList<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();// 2. 內部的 BPPList<BeanPostProcessor> internalPostProcessors = new ArrayList<>();// 3. Ordered 的 BPPList<String> orderedPostProcessorNames = new ArrayList<>();// 4. 普通的 BPPList<String> nonOrderedPostProcessorNames = new ArrayList<>();for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);priorityOrderedPostProcessors.add(pp);// 實現了 MergedBeanDefinitionPostProcessor 為內部的 BPPif (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);}else {nonOrderedPostProcessorNames.add(ppName);}}// PriorityOrdered 的 BPP 排序sortPostProcessors(priorityOrderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);// Next, register the BeanPostProcessors that implement Ordered.// Ordered 的 BPP 排序List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());for (String ppName : orderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);orderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}sortPostProcessors(orderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, orderedPostProcessors);// 普通的 BPP 排序List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());for (String ppName : nonOrderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);nonOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);// Finally, re-register all internal BeanPostProcessors.sortPostProcessors(internalPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, internalPostProcessors);beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

1.2.7 initApplicationEventMulticaster

初始化事件發布器, 用來發布各種事件
默認對象為 SimpleApplicationEventMulticaster

protected void initApplicationEventMulticaster() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();// 如果容器中有了, 使用容器中的if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {this.applicationEventMulticaster =beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);if (logger.isTraceEnabled()) {logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");}}else {// 沒有這里創建一個this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);if (logger.isTraceEnabled()) {logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");}}
}

1.2.8 onRefresh

交由子類實現的鉤子

1.2.9 registerListeners

注冊監聽器

protected void registerListeners() {// 1. 獲取直接注冊到 applicationContext 中的 Listernerfor (ApplicationListener<?> listener : getApplicationListeners()) {getApplicationEventMulticaster().addApplicationListener(listener);}// 2. 獲取容器中所有的 ApplicationListenerString[] 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 (!CollectionUtils.isEmpty(earlyEventsToProcess)) {for (ApplicationEvent earlyEvent : earlyEventsToProcess) {getApplicationEventMulticaster().multicastEvent(earlyEvent);}}
}

1.2.10 finishBeanFactoryInitialization

完成 bean 的初始化, Bean 的創建過程就在這個方法里
內容太多,請查看 1.3 章節

1.2.11 finishRefresh

結束 refresh 方法

protected void finishRefresh() {// 清理緩存clearResourceCaches();// 向容器中添加一個 DefaultLifecycleProcessorinitLifecycleProcessor();// 調用 LifecycleProcessor 的 onRefresh() 方法getLifecycleProcessor().onRefresh();// Publish the final event.publishEvent(new ContextRefreshedEvent(this));// Participate in LiveBeansView MBean, if active.if (!NativeDetector.inNativeImage()) {LiveBeansView.registerApplicationContext(this);}
}

1.3 Bean 的生命周期

1.3.1 入口

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// 。。。// 凍結 BeanFactroy, 就是設置為一個標志位beanFactory.freezeConfiguration();// 實例化 beanbeanFactory.preInstantiateSingletons();
}

1.3.2 preInstantiateSingletons

代碼太多了,直接寫核心流程

// preInstantiateSingletons()
// 1. 處理 FactoryBean
// 2. 調用 getBean()

1.3.3 doGetBean

// 1. 處理 dependsOn
// 2. 處理單實例 bean, 調用 createBean
// 3. 處理 Prototype Bean
// 4. 處理別的 Scope 的 Bean, 例如 request, Session, 擴展: Nacos 的 @RefreshScope 也是這里處理的

1.3.4 createBean

// 1. 處理方法覆蓋
mbdToUse.prepareMethodOverrides();
// 2. 調用 InstantiationAwareBeanPostProcessors 的 applyBeanPostProcessorsBeforeInstantiation() 方
// 2.1 如果這個方法返回了一個Bean, 則說明是我們自主控制了 Bean 的創建, 后續流程將不再執行
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {return bean;
}
// 3. 調用 doCreateBean() 方法創建 Bean
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

1.3.5 doCreateBean

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {// Instantiate the bean.BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}// 創建 Bean 實例// 1. 使用 Supplier 創建// 2. 使用 工廠方法創建// 3. 使用構造器創建if (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);}Object bean = instanceWrapper.getWrappedInstance();Class<?> beanType = instanceWrapper.getWrappedClass();// 。。。// 判斷是否允許提前暴露對象boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {// 添加到三級緩存中// getEarlyBeanReference() 會調用 InstantiationAwareBeanPostProcessor 的 getEarlyBeanReference() 方法// 1. InstantiationAwareBeanPostProcessor 需要注意一個實現類 AbstractAutoProxyCreator, 這個類是用來創建動態代理對象的addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}// 對外暴露的對象Object exposedObject = bean;try {// 填充 bean 屬性populateBean(beanName, mbd, instanceWrapper);// 初始化 beanexposedObject = initializeBean(beanName, exposedObject, mbd);}// ...// 注冊 DisposableBeantry {registerDisposableBeanIfNecessary(beanName, bean, mbd);}/。。。return exposedObject;
}

1.3.6 populateBean

// 1. 執行 InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {return;}}
}
// 2. 處理 BeanDefinition 的 propertyValues

1.3.7 initializeBean 初始化 bean

// 1. 執行 Aware
// 1.1 這里只處理 BeanNameAware,BeanClassLoaderAware,BeanFactoryAware
invokeAwareMethods(beanName, bean);
// 2. 調用 BPP 的 postProcessBeforeInitialization()
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
// 3. 調用初始化方法
// 3.1 InitializingBean 調用 afterPropertiesSet()
// 3.2 調用我們自定義的初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
// 調用  BPP 的 postProcessAfterInitialization()
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

二、各種 BeanPostProcessor(BPP)

在 Bean 的生命周期中常見的可分為 4 種 BPP,可以查看類 BeanPostProcessorCache,不同的 BPP 在 Bean 的生命周期的不同時刻執行。

  1. InstantiationAwareBeanPostProcessor
  2. SmartInstantiationAwareBeanPostProcessor
  3. DestructionAwareBeanPostProcessor
  4. MergedBeanDefinitionPostProcessor

InstantiationAwareBeanPostProcessor

Bean的生命周期中一定是先實例化再初始化。

@Component
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {/*** 實例化之前, 如果這里返回了一個 bean 說明我們需要自主控制 bean 的生命周期* 將不再執行后面的 BPP 和初始化操作*/@Overridepublic Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {return null;}/*** 實例化之后, 只有 before 方法返回的不是一個 null, 才會執行此方法*/@Overridepublic boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {return true;}/*** Bean 執行 afterProperties 的時候調用,可以用來修改屬性綁定* 但是這種并不能用來處理解密數據庫連接, 因為這個流程太過于前置了, bean 還沒有將加密的值綁定上, 這里獲取不到加密的值當然無法解密*/@Overridepublic PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {if (bean instanceof BppBean) {MutablePropertyValues mpvs = (pvs instanceof MutablePropertyValues) ?(MutablePropertyValues) pvs : new MutablePropertyValues();// 會將 name 屬性值修改為 abcmpvs.add("name", "abc");return mpvs;}return pvs;}/*** 跟上面方法功能一樣, 但是這個方法將要被廢棄* 如果 postProcessProperties 返回 null, 則會調用這個方法*/@Overridepublic PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {return pvs;}
}

MergedBeanDefinitionPostProcessor

該接口可以用來操作 BeanDefinition

@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {}

SmartInstantiationAwareBeanPostProcessor

繼承了 InstantiationAwareBeanPostProcessor

@Component
public class MySmartInstantiationAwareBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor {/*** 提前預測 bean 類型* 返回 null 表示不預測*/public Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {if (beanName.equalsIgnoreCase("bppBean")) {return BppBean.class;}return null;}/*** 可以用來指定創建 bean 所用的構造器*/@Overridepublic Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {return SmartInstantiationAwareBeanPostProcessor.super.determineCandidateConstructors(beanClass, beanName);}/*** 如果 bean 從三級緩存中獲取對象, 則會調用這個方法*/@Overridepublic Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {return bean;}
}

DestructionAwareBeanPostProcessor

Bean 銷毀前執行

@Component
public class MyDestructionAwareBeanPostProcessor implements DestructionAwareBeanPostProcessor {/*** 銷毀之前執行*/@Overridepublic void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {System.out.println(beanName + "銷毀之前執行");}/*** false 表示不執行銷毀*/@Overridepublic boolean requiresDestruction(Object bean) {return false;}
}

總結

博主對源碼的理解也很淺顯,如有異議,可于評論區留言,歡迎各位大佬指教。

Bean 的生命周期

getBean() -> doGetBean() -> createBean() -> doCreateBean()

1. preInstantiateSingletons
1.1 處理 FactoryBean
1.2 調用 getBean()2. getBean()
2.1 調用 doGetBean()3. doGetBean()
3.1 處理 DependsOn
3.2 獲取單實例 Bean 調用 createBean()
3.3 獲取多實例 Bean
3.4 處理別的 Scope 類型的Bean, 如 Request,Session4. createBean()
4.1 處理方法覆蓋
4.2 調用 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
4.2.1 如果這里返回了一個Bean 將會調用 BeanPostProcessor#postProcessAfterInitialization。
4.2.2 然后后續的流程將不再處理,直接返回4.2.1 返回的 bean
4.3 調用 doCreateBean() 創建 Bean5. doCreateBean()
5.1 調用 `createBeanInstance` 創建 bean
5.1.1 使用 Supplier 創建 Bean
5.1.2 使用工廠方法創建 Bean
5.1.3 使用構造器創建 Bean5.2 調用 populateBean
5.2.1 調用 InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
5.2.2 處理 BeanDefinition 的 PropertyValues5.3 初始化 initializeBean
5.3.1 執行 Aware; BeanNameAware, BeanClassLoaderAware, BeanFactoryAware
5.3.2 執行 BeanPostProcessor#postProcessBeforeInitialization
5.3.3 執行初始化方法  invokeInitMethods()5.4 invokeInitMethods()
5.4.1 如果是 InitializingBean 執行 afterPropertiesSet
5.4.2 執行自定義的初始化方法

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/916480.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/916480.shtml
英文地址,請注明出處:http://en.pswp.cn/news/916480.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

RS485轉Profinet網關與JRT激光測距傳感器在S7-1200 PLC系統中的技術解析與應用

RS485轉Profinet網關與JRT激光測距傳感器在S7-1200 PLC系統中的技術解析與應用技術核心&#xff1a;協議轉換與數據橋梁在工業自動化系統中&#xff0c;RS485轉Profinet網關承擔著協議翻譯官的角色。以XD-MDPN100型號為例&#xff0c;其本質是將RS485設備的串口數據封裝為Profi…

《C++ string 完全指南:string的模擬實現》

string的模擬實現 文章目錄string的模擬實現一、淺拷貝和深拷貝1.淺拷貝2.深拷貝3.寫時拷貝二、定義string的成員變量三、string的接口實現1.string的默認成員函數&#xff08;1&#xff09;構造函數實現&#xff08;2&#xff09;析構函數實現&#xff08;3&#xff09;拷貝構…

造成服務器內存不足的原因有什么

服務器在日常的運行過程中&#xff0c;會存儲大量關于企業重要的數據信息&#xff0c;偶爾會出現內存飆升空間不足的情況&#xff0c;服務器內存作為服務器數據處理和存儲的主要空間&#xff0c;異常占用會導致服務器性能降低&#xff0c;影響到企業業務的響應速度&#xff0c;…

JVM、Dalvik、ART垃圾回收機制

一、JVM垃圾回收機制&#xff08;桌面/服務器端&#xff09;1. 核心算法&#xff1a;分代收集新生代回收&#xff08;Minor GC&#xff09;觸發條件&#xff1a;Eden區滿時觸發算法&#xff1a;復制算法&#xff08;Eden → Survivor區&#xff09;過程&#xff1a;存活對象在S…

數學專業轉型數據分析競爭力發展報告

一、核心優勢拆解&#xff08;1&#xff09;數學能力與數據分析對應關系數學課程數據分析應用場景比較優勢說明概率論假設檢驗設計能準確判斷統計顯著性閾值實變函數數據質量評估異常值檢測的嚴格性更高線性代數特征工程構建矩陣運算優化模型訓練效率&#xff08;2&#xff09;…

JAVA進階--MySQL

一.MySQL架構連接層:處理客戶端連接服務,認證授權相關的操作服務層:最核心的一層&#xff08;核心服務功能&#xff09;,處理sql,包括sql優化,函數調用....存儲引擎層:存儲引擎是真正負責來操作數據的&#xff08;mysql中數據的存儲和提取&#xff09;, mysql中有不同存儲引擎,…

【架構】Docker簡單認知構建

作為一個之前從來沒有接觸過Docker的倒霉蛋&#xff0c;想了解學習一下Docker 搜了CSDN和RUNOOB&#xff0c;得到的描述如下&#xff1a; Docker 是一個開源的應用容器引擎&#xff0c;基于 Go 語言 并遵從 Apache2.0 協議開源。 Docker 可以讓開發者打包他們的應用以及依賴包…

C++ std::list概念與使用案例

C std::list 概念詳解 std::list 是 C 標準模板庫&#xff08;STL&#xff09;中的一個雙向鏈表容器。與 vector 和 array 不同&#xff0c;它不保證元素在內存中連續存儲&#xff0c;而是通過指針將各個元素連接起來。 核心特性 雙向鏈表結構&#xff1a; 每個元素包含指向前驅…

從0到1學Pandas(六):Pandas 與數據庫交互

目錄一、數據庫基礎操作1.1 連接數據庫1.2 執行 SQL 查詢1.3 創建與修改表結構二、數據導入導出2.1 從數據庫讀取數據2.2 將數據寫入數據庫2.3 大數據量處理三、數據庫事務處理3.1 事務概念與實現3.2 批量數據更新3.3 錯誤處理與回滾四、數據庫性能優化4.1 查詢性能優化4.2 連接…

GitHub 趨勢日報 (2025年07月26日)

&#x1f4ca; 由 TrendForge 系統生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日報中的項目描述已自動翻譯為中文 &#x1f4c8; 今日獲星趨勢圖 今日獲星趨勢圖602Qwen3-Coder573neko527hrms275BillionMail153Win11Debloat115hyperswitch57data…

機器人仿真(2)Ubuntu24.04下RTX5090配置IsaacSim與IsaacLab

目錄 一、前言二、電腦配置三、配置步驟3.1 創建Conda環境3.2 安裝PyTorch3.3 安裝Isaac Sim3.4 安裝Isaac Lab 四、總結 一、前言 博主自從去年開始就一直在關注Isaac Lab和Isaac Sim&#xff0c;但是一直以來由于手頭設備只有4060&#xff0c;甚至沒有達到最低配置16GB顯存要…

DaVinci Resolve 19.0(達芬奇)軟件安裝包下載及詳細安裝教程|附帶安裝文件

[軟件名稱]&#xff1a;ArcGIS [軟件大小]&#xff1a;2.99 GB [系統要求]&#xff1a;支持Win7及更高版本 [下載通道]: 迅雷網盤 [下載鏈接]:高速下載地址 https://pan.xunlei.com/s/VOW9nw-JV99A_7f_5hhpgqO2A1?pwdbufh# ??:先用手機下載迅雷網盤保存到手機中&#xff0c…

Java學習第八十一部分——Shiro

目錄 &#x1f4eb; 一、前言提要簡介 &#x1f6e1;? 二、核心功能介紹 ?? 三、核心架構組件 ? 四、與Java的關系 ?? 五、與Spring Security對比 &#x1f9e9; 六、典型應用場景 &#x1f48e; 七、總結歸納概述 &#x1f4eb; 一、前言提要簡介 Apache Shiro 是…

虛擬機ubuntu20.04共享安裝文件夾

ubuntu20.04共享安裝文件夾 4.5 共享安裝文件夾 將Windows存放安裝文件的文件夾共享給虛擬機&#xff0c;如下圖操作&#xff1a;如果是在ubuntu20.04中&#xff0c;還需要以下的操作&#xff1a; sudo mkdir /mnt/hgfs 此命令無效 sudo echo ‘vmhgfs-fuse /mnt/hgfs fu…

如何查看電腦后門IP和流量?

你是否也有以下經歷&#xff1f;深夜&#xff0c;你的電腦風扇突然狂轉&#xff0c;屏幕卻一片寂靜&#xff1b;每月流量莫名超標&#xff0c;賬單高得離譜&#xff1b;鼠標偶爾不聽使喚…這些可能不是電腦“鬧脾氣”&#xff0c;如何一探究竟&#xff1f; 想象一下&#xff1a…

分類預測 | MATLAB基于四種先進的優化策略改進蜣螂優化算法(IDBO)的SVM多分類預測

分類預測 | MATLAB基于四種先進的優化策略改進蜣螂優化算法(IDBO)的SVM多分類預測 目錄分類預測 | MATLAB基于四種先進的優化策略改進蜣螂優化算法(IDBO)的SVM多分類預測分類效果基本介紹多策略量子自適應螺旋搜索算法研究摘要1. 引言1.1 研究背景1.2 研究意義1.3 研究目標2. 文…

Android 修改系統時間源碼閱讀

鏈接&#xff1a;XRefAndroid - Support Android 16.0 & OpenHarmony 5.0 (AndroidXRef/AospXRef) 這里看的Android 10的代碼&#xff0c;選中Android 10&#xff0c;勾選所有工程&#xff0c;搜索DateTimeSettings?&#xff1a; 看到showTimePicker應該是顯示一個設置時…

關于自定義域和 GitHub Pages(Windows)

GitHub Pages 支持使用自定義域,或將站點 URL 的根目錄從默認值(例如 )更改為您擁有的任何域,比如octocat.github.io。 誰可以使用此功能? GitHub Pages 在公共存儲庫中提供 GitHub Free 和 GitHub Free for organizations,在公共和私有存儲庫中提供 GitHub Pro、GitHub …

自動駕駛領域中的Python機器學習

數據預處理與特征工程 在自動駕駛系統中&#xff0c;數據是驅動決策的核心。從傳感器&#xff08;如攝像頭、激光雷達、毫米波雷達&#xff09;收集的原始數據通常包含噪聲、缺失值和異常值&#xff0c;需要進行系統的預處理。Python的pandas庫提供了強大的數據處理能力&#x…

PROFINET轉CAN通訊協議轉換速通汽車制造

在汽車系統領域之外&#xff0c;控制器局域網&#xff08;CAN&#xff09;總線技術亦廣泛應用于多種工業環境。其固有的穩健性、可靠性與靈活性&#xff0c;使其成為工業自動化及控制系統中設備間通信的理想選擇。CAN 總線技術在工業應用中的關鍵領域包括機器控制、傳感器網絡以…