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

DemoApplication.java

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也可以)途径(事件发布)
		 */

	}

}

Component1.java

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));
    }

}

Component2.java

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("发送短信");
    }

}

UserRegisteredEvent.java

java 复制代码
package com.lucifer.itheima;

import org.springframework.context.ApplicationEvent;


public class UserRegisteredEvent extends ApplicationEvent {
    //source代表事件的事件源,也就是谁发的这个事件
    public UserRegisteredEvent(Object source) {
        super(source);
    }
}

Resource Bundle 'message'目录下

message_en.properties

java 复制代码
hi=hello

message_zh.properties

java 复制代码
hi=你好
相关推荐
我的xiaodoujiao12 分钟前
从 0 到 1 搭建 Python 语言 Web UI自动化测试学习系列 15--二次开发--封装公共方法 3
python·学习·测试工具
立志成为大牛的小牛20 分钟前
数据结构——十四、构造二叉树(王道408)
数据结构·笔记·学习·程序人生·考研
RanceGru42 分钟前
LLM学习笔记5——本地部署ComfyUI和Wan2.1-T2V-1.3B文生视频模型
笔记·学习·stable diffusion·transformer
koo3641 小时前
李宏毅机器学习笔记18
笔记
molong9311 小时前
Activity/Service/Broadcast/ContentProvider 生命周期交互
android·学习·交互
楼田莉子1 小时前
python学习:爬虫+项目测试
后端·爬虫·python·学习
x_lrong1 小时前
个人AI环境快速搭建
人工智能·笔记
嘉年华-cocos1 小时前
高中3500个单词, 纯粹数据版, 助力背诵, 按相似度+从短到长 排序
学习·英语·背单词·音标·记单词
teeeeeeemo1 小时前
Webpack 模块联邦(Module Federation)
开发语言·前端·javascript·笔记·webpack·node.js
阿挥的编程日记1 小时前
基于SpringBoot的高校(学生综合)服务平台的设计与实现
java·spring boot·后端·spring·mybatis