背景
在学习spring知识的时候,spring源码一直是很多人想看懂,但是又看不懂的,很多源码真的是流程复杂又难懂,我刚开始看的时候也是很难受,后面看到很多博客博主,总结了几个心得
- 一定要带着目的去看源码,这个点很重要,不然进去之后很大程度会东看一点西看一点,无头苍蝇一样
- 要善于利用idea自带的快捷查看源码的方便性,比如继承的类,实现的类
- 遇到看不懂的,为什么这样写的,最好去百度查看,因为有些东西不是你目前可以看的到,就明白的
环境准备
- IDEA新建一个maven项目
- 引入pom文件
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.11.RELEASE</version>
</dependency>
</dependencies>
3.创建所需要的类
public interface MessageService {
String getMessage();
}
public class MessageServiceImpl implements MessageService {
@Override
public String getMessage() {
return "hello world";
}
}
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:application.xml");
System.out.println("启动成功");
// 从 context 中取出我们的 Bean
MessageService messageService = context.getBean(MessageService.class);
// 这句将输出: hello world
System.out.println(messageService.getMessage());
}
带着问题
1.IOC的总体流程是怎么样的?
解决第一个问题
从ClassPathXmlApplicationContext点进去,发现了可疑的代码块,debug一下
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
发现是我们传入的路径,看到refresh(),看名字就很可疑,debug进去
进来发现有很多行,大致看看这些名字
prepareRefresh() 准备刷新
obtainFreshBeanFactory() 告诉子类刷新内部 bean 工厂
prepareBeanFactory(beanFactory);准备 bean 工厂以在此上下文中使用
postProcessBeanFactory(beanFactory); 允许在上下文子类中对 bean 工厂进行后处理。
invokeBeanFactoryPostProcessors(beanFactory); 调用在上下文中注册为 bean 的工厂处理器。
registerBeanPostProcessors(beanFactory); 注册拦截 bean 创建的 bean 处理器。
initMessageSource(); 为此上下文初始化消息源。
initApplicationEventMulticaster(); 为此上下文初始化事件多播器。
onRefresh(); 初始化特定上下文子类中的其他特殊 bean。
registerListeners(); 检查监听器 bean 并注册它们。
finishBeanFactoryInitialization(beanFactory); 实例化所有剩余的(非惰性初始化)单例。
finishRefresh(); 最后一步:发布相应的事件。
从上面大致翻译可以看出来ioc容器多初始化流程,至于各个方法的流程,我们就不过多深入进去,如果想要继续深入,那每个方法都需要去看看并且里面逻辑,别忘记了,我们这次是看ioc流程的,不是看其他的