Spring中refresh分析之prepareBeanFactory方法详解

简介: Spring中refresh分析之prepareBeanFactory方法详解

关联博文:

AbstractApplicationContext中refresh方法详解

Spring中refresh分析之prepareRefresh方法详解

Spring中refresh分析之obtainFreshBeanFactory方法详解

Spring中refresh分析之prepareBeanFactory方法详解

Spring中refresh分析之postProcessBeanFactory方法详解

Spring中refresh分析之invokeBeanFactoryPostProcessors方法详解


Spring中refresh分析之registerBeanPostProcessors方法详解

Spring中refresh分析之initMessageSource方法详解

Spring中refresh分析之initApplicationEventMulticaster方法详解

Spring中refresh分析之onRefresh方法详解

Spring中refresh分析之registerListeners方法详解

Spring中refresh分析之finishBeanFactoryInitialization方法详解

Spring中refresh分析之finishRefresh方法详解

接上文Spring中refresh分析之obtainFreshBeanFactory方法详解我们分析过obtainFreshBeanFactory方法后,本文分析prepareBeanFactory方法。



该方法主要是对beanFactory做了一些基础设置的配置,比如BeanClassLoader、BeanExpressionResolver、ApplicationContextAwareProcessor、ApplicationListenerDetector监听器检测器以及默认的环境信息bean。并设置了哪些不需要自动注入以及哪些已经解析过可以直接使用。


① 方法概览

AbstractApplicationContext的prepareBeanFactory方法如下所示。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
  // Tell the internal bean factory to use the context's class loader etc.
  // 设置类加载器,默认是RestartClassLoader
  beanFactory.setBeanClassLoader(getClassLoader());
//设置表达式解析器,比如SPEL语法就是该解析器内维护的SpelExpressionParser进行处理的
  beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//向Set<PropertyEditorRegistrar> propertyEditorRegistrars添加ResourceEditorRegistrar
  beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
  // Configure the bean factory with context callbacks.
  // 为beanFactory配置一些回调,这些在bean实例化过程中会被触发
  beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
  // 向Set<Class<?>> ignoredDependencyInterfaces中添加对象如EnvironmentAware
  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.
  //向Map<Class<?>, Object> resolvableDependencies放入
  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.
// 注册应用监听器检测器,如果实例化bean是ApplicationListener,则其将会被放入applicationListeners
  beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
  // Detect a LoadTimeWeaver and prepare for weaving, if found.
  // 如果loadTimeWeaver 存在于beanFactory,则注册LoadTimeWeaverAwareProcessor
  // 并设置TempClassLoader为ContextTypeMatchClassLoader
  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.
// 如果不包含environment,则注册单例bean,将会放到singletonObjects、registeredSingletons
  if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
    beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
  }
//如果不包含systemProperties,则注册单例bean,将会放到singletonObjects、registeredSingletons
  if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
    beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
  }
//如果不包含systemEnvironment,则注册单例bean,将会放到singletonObjects、registeredSingletons
  if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
    beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
  }
}


方法逻辑梳理如下:


设置类加载器,默认是RestartClassLoader;

设置表达式解析器StandardBeanExpressionResolver,比如SPEL语法就是该解析器内维护的SpelExpressionParser进行处理的;

向Set<PropertyEditorRegistrar> propertyEditorRegistrars添加ResourceEditorRegistrar;

注册beanPostProcessor如ApplicationContextAwareProcessor;

向Set<Class<?>> ignoredDependencyInterfaces中添加对象如EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware;也就是说这些类将不会通过Autowired自动注入而是会被BeanFactory通过比BeanFactoryAware或者ApplicationContext通过ApplicationContextAware这种方式设置。

向Map<Class<?>, Object> resolvableDependencies放入BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext;表示是已经解析的依赖可以直接使用。

注册应用监听器检测器,如果实例化bean是ApplicationListener,则其将会被放入applicationListeners;

如果loadTimeWeaver 存在于beanFactory,则注册LoadTimeWeaverAwareProcessor并设置TempClassLoader为ContextTypeMatchClassLoader

注册默认的环境信息bean如environment、systemProperties、systemEnvironment

② addBeanPostProcessor



关于AbstractBeanFactory的addBeanPostProcessor方法我们可以看一下,如下所示其会根据BeanPostProcessor 的接口类型来对hasInstantiationAwareBeanPostProcessors 、hasDestructionAwareBeanPostProcessors 进行标记。最后将beanPostProcessor放到了beanPostProcessors 里面(其是一个CopyOnWriteArrayList)。

@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
  Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
  // Remove from old position, if any
  this.beanPostProcessors.remove(beanPostProcessor);
  // Track whether it is instantiation/destruction aware
  if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
    this.hasInstantiationAwareBeanPostProcessors = true;
  }
  if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
    this.hasDestructionAwareBeanPostProcessors = true;
  }
  // Add to end of list
  this.beanPostProcessors.add(beanPostProcessor);
}
// beanPostProcessors如下
private final List<BeanPostProcessor> beanPostProcessors = 
new CopyOnWriteArrayList<>();

这个ApplicationContextAwareProcessor也很重要,在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);
  }
}


目录
相关文章
|
30天前
|
Java Spring
【Spring】方法注解@Bean,配置类扫描路径
@Bean方法注解,如何在同一个类下面定义多个Bean对象,配置扫描路径
170 73
|
1月前
|
XML Java 数据格式
Spring Core核心类库的功能与应用实践分析
【12月更文挑战第1天】大家好,今天我们来聊聊Spring Core这个强大的核心类库。Spring Core作为Spring框架的基础,提供了控制反转(IOC)和依赖注入(DI)等核心功能,以及企业级功能,如JNDI和定时任务等。通过本文,我们将从概述、功能点、背景、业务点、底层原理等多个方面深入剖析Spring Core,并通过多个Java示例展示其应用实践,同时指出对应实践的优缺点。
66 14
|
2月前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
44 1
|
3月前
|
存储 安全 Java
|
2月前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
43 1
|
3月前
|
Java BI API
spring boot 整合 itextpdf 导出 PDF,写入大文本,写入HTML代码,分析当下导出PDF的几个工具
这篇文章介绍了如何在Spring Boot项目中整合iTextPDF库来导出PDF文件,包括写入大文本和HTML代码,并分析了几种常用的Java PDF导出工具。
828 0
spring boot 整合 itextpdf 导出 PDF,写入大文本,写入HTML代码,分析当下导出PDF的几个工具
|
3月前
|
XML Java 应用服务中间件
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
300 2
|
2月前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
42 0
|
4月前
|
负载均衡 Java 网络架构
实现微服务网关:Zuul与Spring Cloud Gateway的比较分析
实现微服务网关:Zuul与Spring Cloud Gateway的比较分析
222 5
|
4月前
|
Java 应用服务中间件 Spring
IDEA 工具 启动 spring boot 的 main 方法报错。已解决
IDEA 工具 启动 spring boot 的 main 方法报错。已解决
107 4