• Spring5学习笔记01--BeanFactory 与 ApplicationContext


    第一讲笔记

    内容概要:

    • BeanFactory 能做哪些事
    • ApplicationContext 有哪些扩展功能
    • 事件解耦
    • 什么是BeanFactory
      ConfigurableApplicationContext类图

      • 它是 ApplicationContext 的父接口
        • ApplicationContext 实现了 BeanFactory, 除了 BeanFactory 外的其他接口,就是 ApplicationContext 相对于 BeanFactory 的扩展功能
      • 它才是 Spring 的核心容器,主要的 ApplicationContext 实现都【组合】了它的功能
        • 例如,ApplicationContext的getBean()方法,实际是调用BeanFactory的getBean()方法
        • 【组合】意味着 BeanFactory 实际上是 ApplicationContext 的成员变量
    • BeanFactory 能干点啥
      在这里插入图片描述

      • 查看 BeanFactory 接口所有的方法定义,表面上看只有 getBean
      • 实际上控制反转、基本的依赖注入、直至 Bean 的生命周期的各种功能, 都由它的实现类( DefaultListableBeanFactory )提供
    • ApplicationContext 相对于 BeanFactory, 扩展了哪些功能

      • ApplicationContext 的扩展功能主要体现在它实现的另外4个接口上

      • MessageSource : 处理国际化资源的能力

        • SpringBoot中默认的国际化资源信息存储在以 messages 开头的 properties 文件中
        • 使用 context.getMessage() 方法,获取配置在不同语种下 key 对应的信息
      • ResourcePatternResolver : 使用通配符/路径匹配资源的能力

        • 通配符/路径 比如
          • classpath:开头的是指 类路径下的资源
          • 如果文件在jar包中,使用 classpath: 开头是找不到这个资源的
          • 需要使用 classpath*: 开头获取 jar 包中的资源,比如 classpath*:META-INF/spring.factories
          • classpath:开头的是指 磁盘路径下的资源
        • 使用 context.getResources() 方法,返回对象为 Resource,该类是Spring中对资源的抽象
      • ApplicationEventPublisher : 发布Spring中的 ApplicationEvent 事件对象

        • 事件有发布就有监听,ApplicationEventPublisher 是事件发布器, Spring中的任何一个组件都可以作为事件监听器
        • 1)自定义事件对象,事件对象需要集成 ApplicationEvent,重写构造方法
        class UserRegistEvent extends ApplicationEvent {
        
          // source指当前事件的事件源,谁发的这个事件
        	public UserRegisteredEvent(Object source) {
        		super(source);
        	}
        	
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 2)使用 context.publishEvent() 方法发布事件对象
        // 将ApplicationContext作为事件源
        context.publishEvent(new UserRegisteredEvent(context))
        
        • 1
        • 2
        • 3)监听事件,方法名任意,返回值为void,方法接受一个事件对象的参数,使用@EventListener注解标明当前方法为事件监听器
        @Component
        public class Component1 {
          @EventListener
          public void aaa(UserRegisteredEvent event) {
            // 可以从evnet中获取事件源,用于传递监听到事件后处理逻辑时所需要的上下文信息
            Object source = event.getSource();
          }
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • ApplicationEvent 的作用 : 解耦 (比如:用户注册 + 注册成功后发送短信)
          • Component1 处理用户注册相关逻辑,注册完,Component1发布用户注册成功事件
          • Component2 监听用户注册成功事件,收到事件,Component2 处理发送短信相关逻辑
      • EnvironmentCapable : 可以读取系统中的配置信息(键值对),比如系统环境变量、application.properties

        • 使用 context.getEnvironment() 方法获取配置信息

    事件解耦

    • 目标: 学习ApplicationEvent事件对象,实现功能解耦

    • 知识点: ApplicationEventPublisher 是事件发布器, Spring中的任何一个组件都可以作为事件监听器,使用事件发布器发布事件对象,事件监听器监听并处理事件对象

    • 实现功能: 完成一个用户注册成功后发送短信的功能,在用户注册成功后,发布用户已注册事件;发送短信组件监听该事件后,发送短信。实现用户注册与发送短信解耦

    • 步骤:
      1)自定义事件对象,事件对象需要集成 ApplicationEvent,重写构造方法

    public class UserRegisterEvent extends ApplicationEvent {
    
        /**
         * source指当前事件的事件源,谁发的这个事件
         * @param source
         */
        public UserRegisterEvent(Object source) {
            super(source);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2)使用 applicationContext.publishEvent() 方法发布事件对象

    /**
     * 用户注册服务
     */
    @Slf4j
    @Service
    public class UserRegisterService {
    
        @Autowired
        private ApplicationContext applicationContext;
    
        public User userRegister(String userName) {
            User user = new User();
            user.setUid(UUID.randomUUID().toString().replace("-", ""));
            user.setUserName(userName);
            log.info("user register success, userName:{}", userName);
    
            // 发布用户注册成功事件
            applicationContext.publishEvent(new UserRegisterEvent(user));
    
            return user;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    3)监听事件,方法名任意,返回值为void,方法接受一个事件对象的参数,使用@EventListener注解标明当前方法为事件监听器

    /**
     * 用户注册监听器
     */
    @Slf4j
    @Component
    public class UserRegisterListener {
    
        @EventListener
        public void sendRegisterSuccessMessage(UserRegisterEvent event) {
            // 可以从evnet中获取事件源,用于传递监听到事件后处理逻辑时所需要的上下文信息
            User user = (User) event.getSource();
            log.info("receive user register success event, user:{}", user);
            log.info("send user message success!");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • 相关阅读:
    10.Flink实时项目之订单维度表关联
    Win11鼠标动不了 键盘怎么代替鼠标操作
    Win 11 打开未知文件/打开方式 该文件没有与之关联的应用来执行该操作。请安装应用,若已经安装应用,请在“默认应用设置”页面中创建关联。
    使用PageHelper实现分页查询(详细)
    git下载及基础
    java-net-php-python-jspm校园闲置物品拍卖系统计算机毕业设计程序
    IntelliJ IDEA 安装及创建Java项目
    【C/C++】malloc/free 和 new/delete
    AWS SAP-C02 考试指南
    一款免费无广、简单易用的安全软件:火绒安全软件
  • 原文地址:https://blog.csdn.net/qingqingxiangyang/article/details/126483809