容器接口

  • BeanFactory 接口,典型功能有:
    • getBean
  • ApplicationContext 接口,是 BeanFactory 的子接口。它扩展了 BeanFactory 接口的功能,如:
    • 国际化
    • 通配符方式获取一组 Resource 资源
    • 整合 Environment 环境(能通过它获取各种来源的配置信息)
    • 事件发布与监听,实现组件之间的解耦

image.png

  1. 到底什么是 BeanFactory
    • 它是 ApplicationContext 的父接口
    • 它才是 Spring 的核心容器, 主要的 ApplicationContext 实现都【组合】了它的功能,【组合】是指 ApplicationContext 的一个重要成员变量就是 BeanFactory
  2. BeanFactory 能干点啥
    • 表面上只有 getBean
    • 实际上控制反转、基本的依赖注入、直至 Bean 的生命周期的各种功能,都由它的实现类提供
    • 例子中通过反射查看了它的成员变量 singletonObjects,内部包含了所有的单例 bean
  3. ApplicationContext 比 BeanFactory 多点啥

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

      • 国际化:MessageSource接口—context.getMessage()根据指定的key对应value翻译为不同语言
      • 通配符方式获取一组 Resource 资源:ResourcePatternResolver接口

        1. Resource[] resources = context.getResources("classpath:application.properties");
        2. //添加*表示jar包中也寻找
        3. Resource[] resources1 = context.getResources("classpath*:META-INF/spring.factories");
      • 整合 Environment 环境(处理环境信息如yml配置等) :EnvironmentCapable接口

        1. System.out.println(context.getEnvironment().getProperty("java_home"));
        2. System.out.println(context.getEnvironment().getProperty("server.port"));
      • 事件发布与监听:ApplicationEventPublisher接口

场景:比如注册时,并不确定是发送短信还是邮箱,就可以在注册模块发送一个事件,在其他组件中进行监听处理事件,完成解耦合

  1. public class UserRegisteredEvent extends ApplicationEvent {
  2. public UserRegisteredEvent(Object source) {
  3. super(source);
  4. }
  5. }
  1. @Component
  2. @Slf4j
  3. public class component1 {
  4. @Autowired
  5. private ApplicationEventPublisher context;
  6. public void Register(){
  7. log.info("注册");
  8. //发送事件
  9. context.publishEvent(new UserRegisteredEvent(this));
  10. }
  11. }
  1. @Component
  2. @Slf4j
  3. public class component2 {
  4. @EventListener//表示监听事件
  5. public void listener(UserRegisteredEvent event) {
  6. log.info("{}",event);
  7. log.info("发送短信");
  8. }
  9. }

容器实现

演示1 - DefaultListableBeanFactory

  • beanFactory 可以通过 registerBeanDefinition 注册一个 bean definition 对象
    • 我们平时使用的配置类、xml、组件扫描等方式都是生成 bean definition 对象注册到 beanFactory 当中
    • bean definition 描述了这个 bean 的创建蓝图:scope 是什么、用构造还是工厂创建、初始化销毁方法是什么,等等
  • beanFactory 需要手动调用 beanFactory 后处理器对它做增强
    • 例如通过解析 @Bean、@ComponentScan 等注解,来补充一些 bean definition
  • beanFactory 需要手动添加 bean 后处理器,以便对后续 bean 的创建过程提供增强
    • 例如 @Autowired,@Resource 等注解的解析都是 bean 后处理器完成的
    • bean 后处理的添加顺序会对解析结果有影响,见视频中同时加 @Autowired,@Resource 的例子
  • beanFactory 需要手动调用方法来初始化单例
  • beanFactory 需要额外设置才能解析 ${} 与 #{}

    常见 ApplicationContext 实现

  1. 常见的 ApplicationContext 容器实现
  2. 内嵌容器、DispatcherServlet 的创建方法、作用

Bean的生命周期

image.png

bean 生命周期

创建前后的增强

  • postProcessBeforeInstantiation
    • 这里返回的对象若不为 null 会替换掉原本的 bean,并且仅会走 postProcessAfterInitialization 流程
  • postProcessAfterInstantiation
    • 这里如果返回 false 会跳过依赖注入阶段

依赖注入前的增强

  • postProcessProperties

初始化前后的增强

  • postProcessBeforeInitialization
    • 这里返回的对象会替换掉原本的 bean
    • 如 @PostConstruct、@ConfigurationProperties
  • postProcessAfterInitialization
    • 这里返回的对象会替换掉原本的 bean
    • 如代理增强

销毁之前的增强

收获💡

  1. Spring bean 生命周期各个阶段
  2. 模板设计模式, 指大流程已经固定好了, 通过接口回调(bean 后处理器)在一些关键点前后提供扩展

    模板方法设计模式

    1. public class TestMethodTemplate {
    2. public static void main(String[] args) {
    3. MyBeanFactory beanFactory = new MyBeanFactory();
    4. beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Autowired"));
    5. beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Resource"));
    6. beanFactory.getBean();
    7. }
    8. // 模板方法 Template Method Pattern
    9. static class MyBeanFactory {
    10. public Object getBean() {
    11. Object bean = new Object();
    12. System.out.println("构造 " + bean);
    13. System.out.println("依赖注入 " + bean); // @Autowired, @Resource
    14. for (BeanPostProcessor processor : processors) {
    15. processor.inject(bean);
    16. }
    17. System.out.println("初始化 " + bean);
    18. return bean;
    19. }
    20. private List<BeanPostProcessor> processors = new ArrayList<>();
    21. public void addBeanPostProcessor(BeanPostProcessor processor) {
    22. processors.add(processor);
    23. }
    24. }
    25. static interface BeanPostProcessor {
    26. public void inject(Object bean); // 对依赖注入阶段的扩展
    27. }
    28. }

    Bean 后处理器

  3. @Autowired 等注解的解析属于 bean 生命周期阶段(依赖注入, 初始化)的扩展功能,这些扩展功能由 bean 后处理器来完成

  4. 每个后处理器各自增强什么功能
    • AutowiredAnnotationBeanPostProcessor 解析 @Autowired @Value
    • CommonAnnotationBeanPostProcessor 解析 @Resource、@PostConstruct、@PreDestroy
    • ConfigurationPropertiesBindingPostProcessor 解析 @ConfigurationProperties
  5. 另外 ContextAnnotationAutowireCandidateResolver 负责获取 @Value 的值,解析 @Qualifier、泛型、@Lazy

    @Autowired bean 后处理器运行分析

  6. AutowiredAnnotationBeanPostProcessor.findAutowiringMetadata 用来获取某个 bean 上加了 @Value @Autowired 的成员变量,方法参数的信息,表示为 InjectionMetadata

  7. InjectionMetadata 可以完成依赖注入
  8. InjectionMetadata 内部根据成员变量,方法参数封装为 DependencyDescriptor 类型
  9. 有了 DependencyDescriptor,就可以利用 beanFactory.doResolveDependency 方法进行基于类型的查找

    BeanFactory 后处理器

    BeanFactory 后处理器的作用

  1. @ComponentScan, @Bean, @Mapper 等注解的解析属于核心容器(即 BeanFactory)的扩展功能
  2. 这些扩展功能由不同的 BeanFactory 后处理器来完成,其实主要就是补充了一些 bean 定义