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=你好
相关推荐
经年未远39 分钟前
vue3中实现耳机和扬声器切换方案
javascript·学习·vue
Hill_HUIL40 分钟前
学习日志22-静态路由
网络·学习
莱茶荼菜1 小时前
yolo26 阅读笔记
人工智能·笔记·深度学习·ai·yolo26
q行2 小时前
Spring概述(含单例设计模式和工厂设计模式)
java·spring
詩不诉卿2 小时前
zephyr学习之自定义外部module记录
学习
浮游本尊2 小时前
React 18.x 学习计划 - 第十三天:部署与DevOps实践
学习·react.js·状态模式
好好研究2 小时前
SpringBoot扩展SpringMVC
java·spring boot·spring·servlet·filter·listener
wdfk_prog2 小时前
[Linux]学习笔记系列 -- [drivers][dma]dmapool
linux·笔记·学习
电饭叔2 小时前
Tkinter Button 括号内的核心参数详解
python·学习
NE_STOP3 小时前
spring6-工厂设计模式与bean的实例化方式
spring