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=你好
相关推荐
看山还是山,看水还是。9 分钟前
MySQL 管理
数据库·笔记·mysql·adb
蒲公英100134 分钟前
vue3学习:axios输入城市名称查询该城市天气
前端·vue.js·学习
训山39 分钟前
【11】纯血鸿蒙HarmonyOS NEXT星河版开发0基础学习笔记-模块化语法与自定义组件
笔记·学习·华为·harmonyos·鸿蒙系统
①个程序员1 小时前
thinkphp 学习记录
学习
alfiy2 小时前
Elasticsearch学习笔记(四) Elasticsearch集群安全配置一
笔记·学习·elasticsearch
向上的车轮2 小时前
Django学习笔记十一:部署程序
笔记·学习·django
潘多编程2 小时前
Java中的状态机实现:使用Spring State Machine管理复杂状态流转
java·开发语言·spring
_阿伟_2 小时前
SpringMVC
java·spring
不灭锦鲤2 小时前
ssrf学习(ctfhub靶场)
网络·学习·安全
alfiy3 小时前
Elasticsearch学习笔记(五)Elastic stack安全配置二
笔记·学习·elasticsearch