Spring源码学习
BeanFactory 与 ApplicationContext 的区别
BeanFactory 接口,典型功能有getBean()ApplicationContext 接口,是 BeanFactory 的子接口。它扩展了 BeanFactory 接口的功能,如:国际化通配符方式获取一组 Resource 资源整合 Environment 环境(能通过它获取各种来源的配置信息)事件发布与监听,实现组件之间的解耦
代码演示
代码目录:
A01
@SpringBootApplication
@Slf4j
public class A01 {
public static void main(String[] args) throws Exception{
ConfigurableApplicationContext context = SpringApplication.run(A01.class);
/\*
1. 到底什么是 BeanFactory
- 它是 ApplicationContext 的父接口
- 它才是 Spring 的核心容器, 主要的 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("compo")).forEach((e)->{
System.out.println(e.getKey() + "=" + e.getValue());
});
/\*
3. ApplicationContext 比 BeanFactory 多点啥
\*/
System.out.println(context.getMessage("hi",null, Locale.JAPANESE));
System.out.println(context.getMessage("hi",null, Locale.ENGLISH));
Resource[] resources = context.getResources("classpath\*:META-INF/spring.factories");
for (Resource resource : resources) {
System.out.println(resource);
}
System.out.println(context.getEnvironment().getProperty("java\_home"));
System.out.println(context.getEnvironment().getProperty("server.port"));
context.getBean(Component1.class).register();
}
/\*
4. 学到了什么
a. BeanFactory 与 ApplicationContext 并不仅仅是简单接口继承的关系, ApplicationContext 组合并扩展了 BeanFactory 的功能
b. 又新学一种代码之间解耦途径
\*/
}
Component1
@Component
public class Component1 {
@Resource
private ApplicationEventPublisher context;
public void register(){
System.out.println("用户注册");
context.publishEvent(new UserRegisteredEvent(this));
}
}
Component2
@Component
public class Component2 {
@EventListener
public void aaa(UserRegisteredEvent event){
System.out.println("event:" + event);
System.out.println("发送短信");
}
}
UserRegisteredEvent
public class UserRegisteredEvent extends ApplicationEvent {
public UserRegisteredEvent(Object source) {
super(source);
}
}
代码看不懂 不要着急
代码详解
BeanFactory 与 ApplicationContext 类图
鼠标移动到ConfigurableApplicationContext上,shift + alt + u 打开类关系图:
根据类图可以看出:ApplicationContext比BeanFactory多4个继承接口,分别为:
MessageSource 国际化ResourcePatternResolver 通配符方式获取一组 Resource 资源EnvironmentCapable 整合 Environment 环境(能通过它获取各种来源的配置信息)ApplicationEventPublisher 事件发布与监听,实现组件之间的解耦
BeanFactory
-
1.通过DefaultSingletonBeanRegistry(默认单例Bean注册表)反射拿到属性singletonObjects(一级缓存)DefaultSingletonBeanRegistry管理者Spring中Bean的注入singletonObjects为一级缓存 其与三级缓存(singletonFactoryies),二级缓存(earlySingletonObjects)是为了解决Spring循环依赖而产生
-
2.反射中暴力破解该对象,使其能够调用对应的方法,属性 -
3.通过context调用getBeanFactory()得到beanFactory属性getBeanFactory()是BeanFactory类下的一个方法ApplicationContext继承BeanFactory,则通过方法名直接调用ConfigurableListableBeanFactory也继承于BeanFactory
-
4. 通过get当前beanFactory对象,从一级容器中取出对象
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新