Spring源码学习,20道高频面试题(含答案)

25 阅读3分钟

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. ApplicationContextBeanFactory 多点啥
 \*/
        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. BeanFactoryApplicationContext 并不仅仅是简单接口继承的关系, 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对象,从一级容器中取出对象

img img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取