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


目录
相关文章
|
20天前
|
人工智能 JSON 前端开发
Spring Boot解决跨域问题方法汇总
Spring Boot解决跨域问题方法汇总
|
20天前
|
Java Spring 容器
解决Spring的UnsatisfiedDependencyException异常的方法
在Spring开发中,UnsatisfiedDependencyException异常意味着依赖注入失败,影响应用稳定性。该异常由Spring容器在无法满足bean依赖时抛出,常见原因包括bean定义错误、循环依赖、多个候选bean等。解决方法包括:检查bean定义和注入的正确性、解决循环依赖、确认依赖包的兼容性、使用@Qualifier或@Primary注解。通过日志、调试工具和异常对比来定位问题。持续学习Spring框架有助于更好地解决此类异常。
134 1
|
20天前
|
XML 存储 缓存
【深入浅出Spring原理及实战】「缓存Cache开发系列」带你深入分析Spring所提供的缓存Cache管理器的实战开发指南(修正篇)
【深入浅出Spring原理及实战】「缓存Cache开发系列」带你深入分析Spring所提供的缓存Cache管理器的实战开发指南(修正篇)
39 0
|
20天前
|
Java 关系型数据库 MySQL
【Java Spring开源项目】新蜂(NeeBee)商城项目运行、分析、总结
【Java Spring开源项目】新蜂(NeeBee)商城项目运行、分析、总结
167 4
|
20天前
|
Java Spring
Spring的@Retryable实现方法重试
`@Retryable`注解用于配置异常重试,参数包括:指定异常类型`value`,额外包含异常`include`,排除异常`exclude`,最大尝试次数`maxAttempts`和回退策略`backoff`。可选地,可以用`retryExceptions`列表替换`value`。当重试失败,可使用`@Recover`注解定义恢复逻辑。
20 1
|
20天前
|
Java 微服务 Spring
Spring Boot中获取配置参数的几种方法
Spring Boot中获取配置参数的几种方法
25 2
|
20天前
|
Java 测试技术 开发者
【亮剑】通过自定义注解实现Spring AOP,可以更灵活地控制方法拦截和增强
【4月更文挑战第30天】通过自定义注解实现Spring AOP,可以更灵活地控制方法拦截和增强。首先定义自定义注解,如`@MyCustomAnnotation`,然后创建切面类`MyCustomAspect`,使用`@Pointcut`和`@Before/@After`定义切点及通知。配置AOP代理,添加`@EnableAspectJAutoProxy`到配置类。最后,在需拦截的方法上应用自定义注解。遵循保持注解职责单一、选择合适保留策略等最佳实践,提高代码可重用性和可维护性。记得测试AOP逻辑。
|
20天前
|
存储 缓存 Java
【spring】06 循环依赖的分析与解决
【spring】06 循环依赖的分析与解决
12 1
|
20天前
|
Java 数据库连接 开发者
框架分析(4)-Spring
框架分析(4)-Spring
|
20天前
|
JSON 前端开发 Java
【SpringBoot实战专题】「开发实战系列」全方位攻克你的技术盲区之Spring定义Jackson转换Null的方法和实现案例
【SpringBoot实战专题】「开发实战系列」全方位攻克你的技术盲区之Spring定义Jackson转换Null的方法和实现案例
52 0