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=你好
相关推荐
来生硬件工程师13 分钟前
【硬件笔记】DCDC电源设计—BUCK电路设计要点
笔记·单片机·嵌入式硬件·硬件工程·智能硬件
weixin_4235339919 分钟前
AFSim学习-自定义Processor开发2-将平台状态存储到csv
学习
bu_shuo20 分钟前
计算机二级学习-查找和排序
学习·算法·排序算法
爱奥尼欧20 分钟前
轻量级可扩展日志框架-异步日志与系统集成
开发语言·数据库·c++·学习
MartinYeung523 分钟前
[论文学习]BackdoorLLM:大语言模型后门攻击与防御的综合性基准——深度解析
人工智能·学习·语言模型
nongcunqq35 分钟前
编辑 cookie 的插件
笔记
河阿里37 分钟前
SLF4J深度指南(Java):从原理到 Spring 项目实战
java·开发语言·spring
AOwhisky37 分钟前
kubernetes(K8s)学习笔记:第八期与第九期核心知识点自测与详解
笔记·云原生·kubernetes·云计算·k8s·集群·网络策略
凉、介38 分钟前
KVM + QEMU 虚拟化
笔记·学习·嵌入式·arm·qemu·虚拟化·kvm
承渊政道1 小时前
【MySQL数据库学习】(MySQL访问、连接池原理与简易网站数据流动)
数据库·学习·mysql·mysql访问·连接池原理