浅谈Spring容器

在这里插入图片描述

1.BeanFactory

1.1 什么是BeanFactory

简单来说它是 ApplicationContext 的父接口,也是 Spring 的核心容器, 主要的 ApplicationContext 容器实现都【组合】了 BeanFactory 的功能,【组合】是指 ApplicationContext 的一个重要成员变量就是 BeanFactory

1.2 BeanFactory的作用

① 观察接口查看,表面上只有 getBean 方法

② 实际上控制反转、基本的依赖注入、直至 Bean 的生命周期的各种功能,都由它的实现类提供

③ 例子中通过反射查看了它的成员变量 singletonObjects,内部包含了所有的单例 bean

1.3 ApplicationContext

那么ApplicationContext 比 BeanFactory 多点啥?

① ApplicationContext 组合并扩展了 BeanFactory 的功能

② 国际化、通配符方式获取一组 Resource 资源、整合 Environment 环境、事件发布与监听(四个接口)

2. 容器实现

主要讲下面几种:

① DefaultListableBeanFactory:是 BeanFactory 最重要的实现,像控制反转依赖注入功能,都是它来实现

② AnnotationConfigApplicationContext,Spring boot 中非 web 环境容器

③ AnnotationConfigServletWebServerApplicationContext,Spring boot 中 servlet web 环境容器

2.1 DefaultListableBeanFactory

下面展示如何手动实现 DefaultListableBeanFactory 容器

① beanFactory 可以通过 registerBeanDefinition 注册一个 bean definition 对象

  • 我们平时使用的配置类、xml、组件扫描等方式都是生成 bean definition 对象注册到 beanFactory 当中

  • bean definition 描述了这个 bean 的创建蓝图:scope 是什么、用构造还是工厂创建、初始化销毁方法是什么,等等

    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    // bean 的定义(class, scope, 初始化, 销毁)
    AbstractBeanDefinition beanDefinition =   BeanDefinitionBuilder.genericBeanDefinition(
    					Config.class).setScope("singleton").getBeanDefinition();
    beanFactory.registerBeanDefinition("config", beanDefinition);
    

beanFactory 手动添加 beanFacoty 后处理器:需要手动触发所有已注册的 BeanFactoryPostProcessor,让它们在 Spring 容器真正实例化任何普通 Bean 之前,有机会去“加工”或“修改”容器中的 Bean 定义(BeanDefinition),beanFactory 需要手动调用 beanFactory 后处理器对它做增强

  • 例如通过解析 @Bean、@ComponentScan 等注解,来补充一些 bean definition

beanFactory 手动添加 bean 后处理器,需要手动触发所有已注册的 BeanPostProcessor ,以便对后续 bean 的创建过程提供增强

  • 例如 @Autowired,@Resource 等注解的解析都是 bean 后处理器完成的
  • bean 后处理的添加顺序会对解析结果有影响,见视频中同时加 @Autowired,@Resource 的例子
// 给 BeanFactory 手动添加一些常用的后处理器(beanFacoty 后处理器 和 bean 后处理器 )
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

// BeanFactory 后处理器主要功能,补充了一些 bean 定义,手动激活
beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values()
        .forEach(beanFactoryPostProcessor -> {
    beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
});

// Bean 后处理器, 针对 bean 的生命周期的各个阶段提供扩展,手动激活
beanFactory.getBeansOfType(BeanPostProcessor.class).values().stream()
        .sorted(beanFactory.getDependencyComparator())
        .forEach(beanPostProcessor -> {
    beanFactory.addBeanPostProcessor(beanPostProcessor);
});

④ 手动调用方法来初始化单例

beanFactory.preInstantiateSingletons();

2.2 容器实现的流程总结

① 利用 BeanDefinitionBuilder 创建 BeanDefinition()

② 将 BeanDefinition 注册到 BeanFacotry (这里采用 DefaultListableBeanFactory 实现)

③ BeanFacotry 实现的功能都很基础,所以我们需要补充一些功能

④ 利用工具类 AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory) 添加后处理器

⑤ 当前后处理器只是存在于 BeanDefinition 中,并没有生效工作

⑥ 激活使 BeanFactory 后处理器工作,补充了一些 bean 定义,例如@Bean、@ComponentScan

⑦ 激活使 Bean 后处理器工作,针对 bean 的生命周期的各个阶段提供扩展, 例如 @Autowired @Resource …

… preInstantiateSingleton 使单例立刻创建(提前准备好所有单例)

注:

a.手动激活的时候,应该进行排序操作。有的后置处理器必须最先干活,比如扫描所有 @Autowired 注解、处理依赖注入;有的后置处理器必须最后再执行,比如 AOP 自动代理,需要等所有依赖都准备好了才给 Bean 织入切面。

b. beanFactory 不会做的事

  1. 不会主动调用 BeanFactory 后处理器
  2. 不会主动添加 Bean 后处理器
  3. 不会主动初始化单例
  4. 不会解析 beanFactory 还不会解析 ${ } 与 #{ }

c. bean 后处理器会有排序的逻辑

2.3 其他容器的实现

① ClassPathXmlApplicationContext

​ 根据类路径读取 XML 的 Bean 配置信息

② FileSystemXmlApplicationContext

​ 根据磁盘路径读取 XML 的 Bean 配置信息

① ② 的原理:

​ (1) 使用 XmlBeanDefinitionReader 设置 BeanDefinition 的读取方式,并生成读取对象

​ (2) 然后利用对象的 loadBeanDefinitions 方法,结合 类路径 或者 磁盘路径 读取 XML 文件

③ AnnotationConfigApplicationContext

​ 根据 Java 配置类进行 Bean 的创建,AnnotationConfigApplicationContext 会将常用的后处理器加入到 BeanDefinition 中。XML 文件中可以通过标签开启:<context:annotation-config>

④ AnnotationConfigServletWebServerApplicationContext

​ 根据 Java 配置类进行 Bean 的创建,AnnotationConfigServletWebServerApplicationContext 会将常用的后处理器加入到 BeanDefinition 中,用于 Web 环境

配置类中需要配置:

​ (1):ServletWebServerFactory(内嵌 TomCat 服务器)

​ (2):DispatcherServlet(前置处理器)

​ (3):DispatcherServletRegistrationBean (注册前置处理器并设置地址)

Web 环境

配置类中需要配置:

​ (1):ServletWebServerFactory(内嵌 TomCat 服务器)

​ (2):DispatcherServlet(前置处理器)

​ (3):DispatcherServletRegistrationBean (注册前置处理器并设置地址)

​ (4):Controller(控制器接口)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值