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=你好
相关推荐
Chef_Chen1 分钟前
从0开始学习机器学习--Day25--SVM作业
学习·机器学习·支持向量机
L_cl9 分钟前
Python学习从0到1 day28 Python 高阶技巧 ⑧ 递归
学习
.生产的驴22 分钟前
SpringCloud Gateway网关路由配置 接口统一 登录验证 权限校验 路由属性
java·spring boot·后端·spring·spring cloud·gateway·rabbitmq
vortex527 分钟前
Vim 编辑器学习笔记
学习·编辑器·vim
源于花海29 分钟前
论文学习(四) | 基于数据驱动的锂离子电池健康状态估计和剩余使用寿命预测
论文阅读·人工智能·学习·论文笔记
心怀梦想的咸鱼32 分钟前
Ue5 umg学习(一)
学习·ue5
楚疏笃33 分钟前
鸿蒙学习生态应用开发能力全景图-开发者支持平台(5)
学习·华为·harmonyos
4v1d34 分钟前
边缘计算的学习
人工智能·学习·边缘计算
提高记忆力44 分钟前
SpringBoot整合FreeMarker生成word表格文件
java·spring
B20080116刘实3 小时前
CTF攻防世界小白刷题自学笔记13
开发语言·笔记·web安全·网络安全·php