前言
本合集是学习课程【黑马程序员Spring视频教程,深度讲解spring5底层原理-哔哩哔哩】 https://b23.tv/0ZZD2yX的笔记,主要为课程笔记、练习代码及自己的一些理解,目前计划在两个月内完成学习,暂不涉及web章节
容器和bean
beanfactory和applicationcontext
-
BeanFactory 接口,典型功能有:
-
getBean
-
-
ApplicationContext 接口,是 BeanFactory 的子接口。它扩展了 BeanFactory 接口的功能,如:
-
国际化
-
通配符方式获取一组 Resource 资源
-
整合 Environment 环境(能通过它获取各种来源的配置信息)
-
事件发布与监听,实现组件之间的解耦
-
package com.butch.a01;
//beanfactory和applicationtext
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
public class A01 {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException {
ConfigurableApplicationContext context = SpringApplication.run(A01.class, args);
/*ConfigurableApplicationContext的父接口是applicationcontext,其本质上还是一个beanfactory
beanfactory是spring的核心容器,ioc功能主要来源,applicationcontext组合了其功能
*/
System.out.println("context = " + 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.entrySet().stream()
.filter(e -> e.getKey().startsWith("com"))
.forEach(e -> {
System.out.println(e.getKey() + "=" + e.getValue());
});
/*
application比beanfacoty功能更加强大,继承更多接口
EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver
*/
//国际化MessageSource接口
System.out.println(context.getMessage("hi", null, Locale.CHINA));
System.out.println(context.getMessage("hi", null, Locale.ENGLISH));
System.out.println(context.getMessage("hi", null, Locale.JAPANESE));
//资源解析接口ResourcePatternResolver
Resource[] resource = context.getResources("classpath*:META-INF/spring.factories");
for (Resource resource1 : resource) {
System.out.println("resource1 = " + resource1.toString());
}
//系统环境配置接口
System.out.println(context.getEnvironment().getProperty("java_home"));
System.out.println(context.getEnvironment().getProperty("server.port"));
//事件发布器接口
Component1 component1 = context.getBean(Component1.class);
component1.register();
/*
总结:
1.applicationcontext的一个子接口,除了组合beanfactory的功能,还通过继承其他接口增强的自己的功能
2.其中事件发布接口,更好的解耦不同的流程,其处理逻辑类似mq
*/
}
}
package com.butch.a01;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
@Component
public class Component1 {
private static final Logger log = LoggerFactory.getLogger(Component1.class);
@Autowired
private ApplicationEventPublisher context;
public void register() {
log.debug("用户注册");
context.publishEvent(new UserRegisteredEvent(this));
}
}
package com.butch.a01;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@Component
public class Component2 {
private static final Logger log = LoggerFactory.getLogger(Component2.class);
@EventListener
public void add(UserRegisteredEvent event){
log.debug("{}", event);
log.debug("发送短信");
}
}
package com.butch.a01;
import org.springframework.context.ApplicationEvent;
public class UserRegisteredEvent extends ApplicationEvent {
public UserRegisteredEvent(Object source) {
super(source);
}
}