- 三哥
内容来自【自学星球】
欢迎大家来了解我的星球,和星主(也就是我)一起学习 Java ,深入 Java 体系中的所有技术。我给自己定的时间是一年,无论结果如何,必定能给星球中的各位带来点东西。
想要了解更多,欢迎访问👉:自学星球
--------------SSM系列源码文章及视频导航--------------
创作不易,望三连支持!
SSM源码解析视频
👉点我
Spring
- Spring 中注入 Bean 的各种骚操作做
- Spring 中Bean的生命周期及后置处理器使用
- Spring 中容器启动分析之refresh方法执行之前
- Spring refresh 方法分析之一
- Spring refresh 方法之二 invokeBeanFactoryPostProcessors 方法解析
- Spring refresh 方法分析之三
- Spring refresh 方法之四 finishBeanFactoryInitialization 分析
- Spring AOP源码分析一
- Spring AOP源码分析二
- Spring 事务源码分析
SpringMVC
MyBatis
- MyBatis 源码分析之 SqlSessionFactory 创建
- MyBatis 源码分析之 SqlSession 创建
- MyBatis 源码分析之 Mapper 接口代理对象生成及方法执行
- MyBatis 源码分析之 Select 语句执行(上)
- MyBatis 源码分析之 Select 语句执行(下)
- MyBatis 源码分析一二级缓存
---------------------【End】--------------------
一、refresh 方法之 registerBeanPostProcessors
下面我们来分析这个注册 Bean 的后置处理器方法,这里仅仅只是注册,调用阶段则是在 Bean 进行实例化的时候调用。
方法入口
registerBeanPostProcessors(beanFactory);
进入
org.springframework.context.support.AbstractApplicationContext#registerBeanPostProcessors
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 1.注册BeanPostProcessor
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
再进入会来到真正注册的方法
org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 找出所有实现BeanPostProcessor接口的类
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
// 获取 BeanPostProcessor 类型数量
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
// 添加BeanPostProcessorChecker(主要用于记录信息)到beanFactory中
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 定义不同的变量用于区分: 实现PriorityOrdered接口的BeanPostProcessor、实现Ordered接口的BeanPostProcessor、普通BeanPostProcessor
// priorityOrderedPostProcessors: 用于存放实现PriorityOrdered接口的BeanPostProcessor
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// internalPostProcessors: 用于存放Spring内部的BeanPostProcessor
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
// orderedPostProcessorNames: 用于存放实现Ordered接口的BeanPostProcessor的beanName
List<String> orderedPostProcessorNames = new ArrayList<>();
// nonOrderedPostProcessorNames: 用于存放普通BeanPostProcessor的beanName
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
// 遍历postProcessorNames, 将 BeanPostProcessors 按类型区分开
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 如果ppName对应的Bean实例实现了PriorityOrdered接口, 则拿到ppName对应的Bean实例并添加到priorityOrderedPostProcessors
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
// 如果ppName对应的Bean实例也实现了MergedBeanDefinitionPostProcessor接口,
// 则将ppName对应的Bean实例添加到internalPostProcessors
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
// 如果ppName对应的Bean实例没有实现PriorityOrdered接口, 但是实现了Ordered接口, 则将ppName添加到orderedPostProcessorNames
orderedPostProcessorNames.add(ppName);
}
else {
// 否则, 将ppName添加到nonOrderedPostProcessorNames
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
// 首先, 注册实现PriorityOrdered接口的BeanPostProcessors
// 对priorityOrderedPostProcessors进行排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 注册priorityOrderedPostProcessors
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
// 接下来, 注册实现Ordered接口的BeanPostProcessors
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
// 拿到ppName对应的BeanPostProcessor实例对象
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
// 将ppName对应的BeanPostProcessor实例对象添加到orderedPostProcessors, 准备执行注册
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
// 如果ppName对应的Bean实例也实现了MergedBeanDefinitionPostProcessor接口,
// 则将ppName对应的Bean实例添加到internalPostProcessors
internalPostProcessors.add(pp);
}
}
// 对orderedPostProcessors进行排序
sortPostProcessors(orderedPostProcessors, beanFactory);
// 注册orderedPostProcessors
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
// 注册所有常规的BeanPostProcessors
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
// 最后, 重新注册所有内部BeanPostProcessors(相当于内部的BeanPostProcessor会被移到处理器链的末尾)
sortPostProcessors(internalPostProcessors, beanFactory);
// 注册internalPostProcessors
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
// 重新注册ApplicationListenerDetector( 主要是为了移动到处理器链的末尾)
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
这个方法和 invokeBeanFactoryPostProcessors 方法的流程有点类似,先找到所有符合类型的类,然后按照不同类型进行处理,那对应上面的源码还是来总结一下干了些啥。
- 获取所有的实现 BeanPostProcessor 接口的类
- 记录获取到的 BeanPostProcessor 数量,并添加了一个用于记录信息的后置处理器
- 创建存放不同类型的集合,用于区分获取到的 BeanPostProcessor 类
- 先注册实现 PriorityOrdered接口的 BeanPostProcessor,并且判断是否还实现了 MergedBeanDefinitionPostProcessor,如果是则存放 internalPostProcessors 集合中
- 后注册实现了 Ordered 接口的 BeanPostProcessor,并且判断是否还实现了 MergedBeanDefinitionPostProcessor,如果是则存放 internalPostProcessors 集合中
- 接着注册普通的 BeanPostProcessor,并且判断是否还实现了 MergedBeanDefinitionPostProcessor,如果是则存放 internalPostProcessors 集合中
- 最后注册 internalPostProcessors 集合中的 BeanPostProcessor 。
以上流程很好理解,不是很难,那我们接着来看看 BeanPostProcessor 是如何注册的吧,也即 registerBeanPostProcessors 方法。
方法源码
org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
// 遍历传入的后置处理器集合,依次放入 BeanFactory 中
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}
在进入 addBeanPostProcessor 方法
org.springframework.beans.factory.support.AbstractBeanFactory#addBeanPostProcessor
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
// 如果beanPostProcessor已经存在则移除(可以起到排序的效果,beanPostProcessor可能本来在前面,移除再添加,则变到最后面)
this.beanPostProcessors.remove(beanPostProcessor);
// 将beanPostProcessor添加到beanPostProcessors中
this.beanPostProcessors.add(beanPostProcessor);
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
// 如果beanPostProcessor是InstantiationAwareBeanPostProcessor, 则将hasInstantiationAwareBeanPostProcessors设置为true,
// 该变量用于指示beanFactory是否已注册过InstantiationAwareBeanPostProcessors
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
// 如果beanPostProcessor是DestructionAwareBeanPostProcessor, 则将hasInstantiationAwareBeanPostProcessors设置为true,
// 该变量用于指示beanFactory是否已注册过DestructionAwareBeanPostProcessor
this.hasDestructionAwareBeanPostProcessors = true;
}
}
方法很简单,就是向 beanPostProcessors 属性添加值,并做一些额外处理。
二、refresh 方法之 initMessageSource
这个方法比较简单,主要作用就是初始化国际化文件。
那我们先来看案例:
1、配置两个文件
2、编写配置类
@Configuration
public class LifeConfiguration {
// Bean 的名称必须要是 messageSource
@Bean(name = "messageSource")
public MessageSource getMessageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setDefaultEncoding("UTF-8");
messageSource.addBasenames("message", "message_en");
return messageSource;
}
}
3、测试
public class LifeMain {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(LifeConfiguration.class);
MessageSource messageSource = applicationContext.getBean(MessageSource.class);
String zhMessage = messageSource.getMessage("user.name", null, null, Locale.CHINA);
String enMessage = messageSource.getMessage("user.name", null, null, Locale.ENGLISH);
System.out.println("zhMessage = " + zhMessage);
System.out.println("enMessage = " + enMessage);
}
}
ok,现在知道使用了,那我们进入正题,源码分析。
切入口
initMessageSource();
org.springframework.context.support.AbstractApplicationContext#initMessageSource
protected void initMessageSource() {
// 获取 BeanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 判断beanFactory中是否有名字为messageSource的bean
// MESSAGE_SOURCE_BEAN_NAME = "messageSource";
// 如果没有,新建DelegatingMessageSource类作为messageSource的Bean。
// 如果有,从beanFactory中获取
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
// 从容器中获取 BeanName 为 messageSource 类型为 MessageSource 的 Bean 实例, 并将其赋值给当前容器内部的 MessageSource
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
// 判断父类是否不为空 && 当前对象的 messageSource 是 HierarchicalMessageSource 的实例
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
// 将 HierarchicalMessageSource 的父 MessageSource 赋值为 getInternalParentMessageSource()
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isDebugEnabled()) {
logger.debug("Using MessageSource [" + this.messageSource + "]");
}
}
else {
// Use empty MessageSource to be able to accept getMessage calls.
// 容器中不存在 BeanName 为 messageSource 的 Bean 实例
// 手动创建一个 DelegatingMessageSource 实例, 用于接受 getMessage 方法调用。
DelegatingMessageSource dms = new DelegatingMessageSource();
// 添加父类 MessageSource
dms.setParentMessageSource(getInternalParentMessageSource());
// 将手动创建的 DelegatingMessageSource 赋值给当前容器中的 messageSource
this.messageSource = dms;
// 以 messageSource 为 BeanNme 将 DelegatingMessageSource 类的实例注册到一级缓存 singletonObjects 中
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
"': using default [" + this.messageSource + "]");
}
}
}
源码很简单,就是给 this.messageSource 属性赋值,但有一点我们要注意就是,手动注入 MessageSource 类型的 Bean 名称必须是 “messageSource”。
三、refresh 方法之 initApplicationEventMulticaster
这部分和 Spring 的事件监听机制有所关联,那我们按照惯例先来了解了解 Spring 的事件监听如何使用。
Spring 的事件监听主要分三部分:
- 事件:ApplicationEvent,要自定义事件,则需要创建一个类继承 ApplicationEvent。
- 事件发布者:ApplicationEventPublisher 和 ApplicationEventMulticaster,因为 ApplicationContext 实现了 ApplicationEventPublisher,所以事件发布可以直接使用 ApplicationContext。
- 事件监听器:ApplicationListener,通过创建一个实现了 ApplicationListener 并注册为 Spring bean 的类来接收消息。
既然如此,我们实现一个自己的监听器就需要完成下面三件事情:
- 自定义一个事件
- 向 IOC 容器中注册我们自己的监听器
- 发布事件
现在目标很明确了,那开始编写案例:
1、自定义事件
public class MyEvent extends ApplicationEvent {
private String message;
public MyEvent(Object source, String message) {
super(source);
this.message = message;
}
public String getMessage() {
return message;
}
}
2、写一个自己的监听器,监听器的关注事件为 MyEvent
@Component
public class MyApplicationListener implements ApplicationListener<MyEvent> {
@Override
public void onApplicationEvent(MyEvent event) {
System.out.println("MyApplicationListener 收到消息: " + event.getMessage());
}
}
3、编写配置类
@Configuration
@ComponentScan(value = "cn.j3code.studyspring.listener")
public class MyListenerConfiguration {
}
4、测试
public class MyListenerMain {
public static void main(String[] args) {
// 读取配置文件启动
AnnotationConfigApplicationContext annotationApplicationContext =
new AnnotationConfigApplicationContext(MyListenerConfiguration.class);
// 手动发布事件
annotationApplicationContext.publishEvent(new MyEvent(annotationApplicationContext, "我发布的一个消息,记得关注点赞"));
}
}
现在我们进入这个源码,看看其实现原理。
入口
initApplicationEventMulticaster();
org.springframework.context.support.AbstractApplicationContext#initApplicationEventMulticaster
protected void initApplicationEventMulticaster() {
// 获取 BeanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 判断 beanFactory 中是否存在事件广播中心bean实例
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
//存在时,beanFactory中的事件广播中心bean实例赋值给applicationEventMulticaster
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
// 不能存在,new 创建新的applicationEventMulticaster并赋值给applicationEventMulticaster
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
// 将创建的新事件广播中心bean实例注册到单例bean注册中心
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}
该方法和 initMessageSource 方法步骤非常相似,先判断容器中是否存在对应的 Bean ,如果存在则不做处理,反之则向容器中添加相关 Bean。
当然 Spring 的事件监听机制在这里只是一个开始,还需要结合 registerListeners 方法才能实现监听功能,下节就来分析分析它。
四、refresh 方法之 onRefresh
空方法,需要子类实现
protected void onRefresh() throws BeansException {
// For subclasses: do nothing by default.
}
五、refresh 方法之 registerListeners
19 节中我们分析了多播器的初始化,而这次要介绍的就是向多播器中添加其它两个中要的组件:Listeners
、Event
。
方法源码
org.springframework.context.support.AbstractApplicationContext#registerListeners
protected void registerListeners() {
// Register statically specified listeners first.
// 优先在事件多播器中 注册静态指定的监听器
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
// 获取实现ApplicationListener接口的监听器
// 这个阶段监听器没有初始化
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
// 获取事件多播器 ,并将实现ApplicationListener接口的Bean注册到applicationListenerBeans中
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
// earlyApplicationEvents是早期的事件,在Spring IOC整个生命周期中,比多播期的初始化要早出现
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
// 赋值为null, help gc
this.earlyApplicationEvents = null;
// 存储早期事件的集合被初始化
if (earlyEventsToProcess != null) {
// 遍历事件
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
// //添加到多播器中
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
方法很简单,就是向多播器中添加 Listeners 和 Event ,这样多播器对象就可以实现事件广播功能。
好了,今天的内容到这里就结束了,我是 【J3】关注我,我们下期见
。
-
由于博主才疏学浅,难免会有纰漏,假如你发现了错误或偏见的地方,还望留言给我指出来,我会对其加以修正。
-
如果你觉得文章还不错,你的转发、分享、点赞、留言就是对我最大的鼓励。
-
感谢您的阅读,十分欢迎并感谢您的关注。