• 【spring-01】容器接口


    第一讲 容器接口

    容器接口

    • BeanFactory能做那些事
    • ApplicationContext有哪些扩展功能
    • 事件解耦

    [001]-BeanFactory与ApplicationContext

    @SpringBootApplication
    public class Spring01Application {
        public static void main(String[] args) throws Exception {
    
            ConfigurableApplicationContext context = SpringApplication.run(Spring01Application.class, args);
            // ----class org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
            System.out.println("----"+context.getClass());
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    打印 context.getClass() ,springBoot的启动程序返回的ConfigurableApplicationContext 的具体实现类是AnnotationConfigServletWebServerApplicationContext

    AnnotationConfigServletWebServerApplicationContext又间接继承了GenericApplicationContext,在这个类里面可以找到beanFactory作为成员变量出现。

    在这里插入图片描述

    在这里插入图片描述

    到底什么是BeanFactory

    1. 它是 ApplicationContext 的父接口
    2. 它才是 Spring 的核心容器,主要的 ApplicationContext 实现都【组合】了它的功能

    在这里插入图片描述

    [002]-BeanFactory功能

    查看springBoot 默认的ConfigurableApplicationContext 类中的BeanFactory的实际类型

     ConfigurableApplicationContext context = SpringApplication.run(Spring01Application.class, args);
            // ----class org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
            System.out.println("----"+context.getClass());
    
            // class org.springframework.beans.factory.support.DefaultListableBeanFactory
            System.out.println(context.getBeanFactory().getClass());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    实际的结果为DefaultListableBeanFactory

    类图

    在这里插入图片描述

    先看DefaultListableBeanFactory的父类DefaultSingletonBeanRegistry,选中,按F4,跳对于源码

    有一个私有成员变量singletonObjects

    在这里插入图片描述

    通过反射获取该成员变量

    反射获取成员变量步骤

        public static void main(String[] args) throws Exception {
    
            ConfigurableApplicationContext context = SpringApplication.run(Spring01Application.class, args);
            ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
    
            Field singletonObjects = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
            singletonObjects.setAccessible(true);
            // 通过反射获取 beanFactory 对象的值
            Map<String, Object> map = (Map<String, Object>) singletonObjects.get(beanFactory);
    
            map.forEach((k,v)->{
                System.out.println(k+"===="+v);
            });
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    [003]-ApplicationContext功能

    ApplicationContext 比 BeaFactory多实现了4个接口

    • MessageSource: 国际化功能,支持多种语言
    • ResourcePatternResolver: 通配符匹配资源路径
    • EnvironmentCapable: 环境信息,系统环境变量,*.properties*.application.yml等配置文件中的值
    • ApplicationEventPublisher: 发布事件对象

    在这里插入图片描述

    1.MessageSource

    在这里插入图片描述

    在文件中定义不同的值

    hi=hello
    hi=こんにちは
    hi=你好
    
    • 1
    • 2
    • 3
    ConfigurableApplicationContext context = SpringApplication.run(Spring01Application.class, args);
    ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
    
    System.out.println(context.getMessage("hi", null, Locale.CHINA));
    System.out.println(context.getMessage("hi", null, Locale.ENGLISH));
    System.out.println(context.getMessage("hi", null, Locale.JAPANESE));
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.ResourcePatternResolver

    **例1.**获取类路径下的messages开头的配置文件

    Resource[] resources = context.getResources("classpath:messages*.properties");
    for (Resource resource : resources) {
        System.out.println(resource);
    }
    
    • 1
    • 2
    • 3
    • 4

    **例2.**获取spring相关jar包中spring.factories配置文件

    Resource[] resources = context.getResources("classpath*:META-INF/spring.factories");
    for (Resource resource : resources) {
        System.out.println(resource);
    }
    
    • 1
    • 2
    • 3
    • 4

    3.EnvironmentCapable

    获取系统环境变量中 java_home 和项目的 application.yml 中的server.port属性

    System.out.println(context.getEnvironment().getProperty("java_home"));
    System.out.println(context.getEnvironment().getProperty("server.port"));
    
    • 1
    • 2

    4. ApplicationEventPublisher

    • context.publishEvent()——发布事件
    @Component
    @Slf4j
    public class UserService {
        @Autowired
        private ApplicationEventPublisher context;
        public void register(String username, String password) {
            log.info("新用户注册,账号:" + username + ",密码:" + password);
            context.publishEvent(new UserRegisteredEvent(this));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    发表事件的来源——继承ApplicationEvent

    public class UserRegisteredEvent extends ApplicationEvent {
        public UserRegisteredEvent(Object source) {
            super(source);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    监听事件——@EventListener

    @Component
    @Slf4j
    public class UserRegisteredListener {
        @EventListener
        public void userRegist(UserRegisteredEvent event) {
            System.out.println("UserRegisteredEvent...");
            log.info("{}", event);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 相关阅读:
    Cocos2d Opengl2.1 升级到 opengl3.3
    strcpy和strcat和strlen操作(char数组)
    UE4 基础篇十四:自定义插件
    混合IT基础设施的安全挑战与缓解策略
    格拉姆角场GAF将时序数据转换为图像并应用于东南大学轴承故障诊断(Python代码,CNN模型)
    Java(SpringBoot04)
    深度学习环境 | pycharm+cuda+pytorch
    springmvc源码之Web上下文初始化
    thinkphp:判断数据是否存在,再作为数据库的判断条件(给数据库查询增加额外的查询条件)
    [项目管理-20]:流水线pipeline与项目管理
  • 原文地址:https://blog.csdn.net/qq_25614773/article/details/126219052