• Spring底层原理学习笔记--第一讲--(BeanFactory与ApplicaitonContext)


    DemoApplication.java

    package com.lucifer;
    
    import com.lucifer.itheima.Component1;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    import org.springframework.beans.factory.support.DefaultSingletonBeanRegistry;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.ConfigurableApplicationContext;
    import org.springframework.core.io.Resource;
    
    import java.io.IOException;
    import java.lang.reflect.Field;
    import java.util.Locale;
    import java.util.Map;
    
    
    @SpringBootApplication(scanBasePackages = {"com.lucifer"})
    
    public class DemoApplication {
    
    	public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException {
    
    		/**
    		 * 1.什么是BeanFactory
    		 * 是ApplicationContext的父接口
    		 * 是Spring的核心容器,主要的ApplicaitonContext实现都【组合】了它的功能
    		 *
    		 * ctrl+alt+u 查看接口的继承关系
    		 * ctrl+f12 查看接口有哪些方法
    		 * ctrl+v 自动生成表达式的返回值
    		 */
    		ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
    //		context.getBean("aaaa");
    		System.out.println(context);
    
    		/**
    		 2.BeanFactory能干啥
    		 表面上只有getBean
    		 实际上控制反转,基本的依赖注入,直至Bean的生命周期的各种功能,都由它的实现类提供
    		 */
    		Field singletonObjects = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
    		singletonObjects.setAccessible(true);
    		ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
    
    		Map<String, Object> map = (Map<String, Object>) singletonObjects.get(beanFactory);
    //		map.forEach((k,v)->{
    //			System.out.println(k + "=" +v);
    //		});
    
    		map.entrySet().stream().filter(e->e.getKey().startsWith("component")).forEach(e-> System.out.println(e.getKey()+ "=" +e.getValue()));
    
    		/**
    		 * 3.ApplicationContext 比 BeanFactory多点哈
    		 */
    		/**
    		 * 3.1国际化
    		 */
    		System.out.println(context.getMessage("hi", null, Locale.CHINA));
    		System.out.println(context.getMessage("hi",null,Locale.ENGLISH));
    
    		/**
    		 * 3.2根据通配符能获取一组资源
    		 */
    		//classpath 是类路径下   file 指的是磁盘下面  classpath只是到类路径下,jar包的找不到,classpath* 能找到jar包下的
    //		Resource[] resources = context.getResources("classpath:application.properties");
    		Resource[] resources = context.getResources("classpath*:META-INF/spring.factories");
    		for (Resource resource:resources) {
    			System.out.println(resource);
    		}
    
    		/**
    		 * 3.3获取一些配置信息(配置信息来自环境变量或者我们的配置文件)
    		 */
    		//environment是一些配置信息 配置信息的源可能多种多样 有的来自环境变量的键值,有的来自application.properties的键值
    		//不区分大小写
    		System.out.println(context.getEnvironment().getProperty("java_home"));
    		System.out.println(context.getEnvironment().getProperty("server.port"));
    
    		/**
    		 * 3.4发布事件((发布事件的最大作用,实现组件之间的解耦)
    		 */
    		// context是事件源 也就是发布事件
    		// 收事件叫监听器,在spring中任何一个组件都可以作为监听器,比如我们的Component1,Component2
    		// 在这我们把component2作为监听器
    		//context.publishEvent(new UserRegisteredEvent(context));
    		context.getBean(Component1.class).register();
    
    		/**
    		 * 4.学到了什么
    		 * 	  a. BeanFactory 与 ApplicationContext 并不仅仅是简单接口继承的关系,ApplicaitonContext组合并扩展了BeanFactory的功能
    		 * 	  b. 学到了一种新的代码之间解耦(aop也可以)途径(事件发布)
    		 */
    
    	}
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97

    Component1.java

    package com.lucifer.itheima;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.ApplicationEventPublisher;
    import org.springframework.stereotype.Component;
    
    
    @Slf4j
    @Component
    public class Component1 {
    
        @Autowired
        private ApplicationEventPublisher context;
    
        public void register() {
            log.info("用户注册");
            context.publishEvent(new UserRegisteredEvent(this));
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    Component2.java

    package com.lucifer.itheima;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.context.event.EventListener;
    import org.springframework.stereotype.Component;
    
    @Slf4j
    @Component
    public class Component2 {
    
        @EventListener
        public void aaa(UserRegisteredEvent event) {
            log.info("{}",event);
            log.info("发送短信");
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    UserRegisteredEvent.java

    package com.lucifer.itheima;
    
    import org.springframework.context.ApplicationEvent;
    
    
    public class UserRegisteredEvent extends ApplicationEvent {
        //source代表事件的事件源,也就是谁发的这个事件
        public UserRegisteredEvent(Object source) {
            super(source);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    Resource Bundle 'message’目录下

    message_en.properties

    hi=hello
    
    • 1

    message_zh.properties

    hi=你好
    
    • 1
  • 相关阅读:
    Effective C++改善程序与设计的55个具体做法 3. 资源管理
    js中的promise函数(ES6)
    Docker 容器闪退,Docker exited 0原因分析及解决
    博迪投资学·资本市场:第9、14、16章的模型总结
    SSH免密登陆 配置方法(Mac、Win)
    Python教程:迭代器的正确使用方法
    详解csrf(跨站请求伪造)
    dumpstate log总结
    GPT实战系列-P-Tuning本地化训练ChatGLM2等LLM模型,到底做了什么?(二)
    战略篇-EMC三板斧
  • 原文地址:https://blog.csdn.net/weixin_42594143/article/details/134199051