本人本科毕业,21届毕业生,一年工作经验,简历专业技能如下,现根据简历,并根据所学知识复习准备面试。
记录日期:2022.1.4
大部分知识点只做大致介绍,具体内容根据推荐博文链接进行详细复习。
文章目录
框架原理 - Spring(十四)之Spring IOC 源码finishRefresh()
AbstractApplicationContext#finishRefresh()
刷新完成工作,包括初始化 LifecycleProcessor
,发布刷新完成事件等。
@SuppressWarnings("deprecation")
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
// 1. 清空上下文级别的资源缓存
clearResourceCaches();
// Initialize lifecycle processor for this context.
// 2. 为此上下文初始化生命周期处理器
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
// 3. 首先将刷新完毕事件传播到生命周期处理器(触发isAutoStartup方法返回true的SmartLifecycle的start方法)
getLifecycleProcessor().onRefresh();
// Publish the final event.
// 4. 推送上下文刷新完毕事件到相应的***
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
if (!NativeDetector.inNativeImage()) {
// 5. 注册MBean,通过JMX进行监控和管理
LiveBeansView.registerApplicationContext(this);
}
}
initLifecycleProcessor()
我们一起来看 finishRefresh()
代码块的 2
中。
ApplicationContext
在启动或停止时, 它会通过 LifecycleProcessor
来与所有声明的Bean的周期做状态更新,这一步就是初始化LifecycleProcessor
。
需要注意的是,Spring会先从容器中获取BeanName为 "lifecycleProcessor"
的Bean实例,如果没有则使用Spring默认的DefaultLifecycleProcessor
。所以开发者需要自定义LifecycleProcessor
时一定需要将自己定义的LifecycleProcessor
声明为 "lifecycleProcessor"
。
// LIFECYCLE_PROCESSOR_BEAN_NAME = "lifecycleProcessor";
protected void initLifecycleProcessor() {
// 1. 获取当前 BeanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 2. 判断BeanFactory是否已经存在生命周期处理器
if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
// 2.1 如果已经存在,则将该bean赋值给lifecycleProcessor
this.lifecycleProcessor =
beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
if (logger.isTraceEnabled()) {
logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
}
}
else {
// 2.2 如果不存在,则使用DefaultLifecycleProcessor
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
this.lifecycleProcessor = defaultProcessor;
// 并将DefaultLifecycleProcessor作为默认的生命周期处理器,注册到BeanFactory中
beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
if (logger.isTraceEnabled()) {
logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
}
}
}
getLifecycleProcessor().onRefresh()
我们一起来看 finishRefresh()
代码块的 3
中。
将LifecycleProcessor
初始化完成之后,调用LifecycleProcessor
接口的onRefresh()
方法刷新所有实现了Lifecycle
的Bean
。
LifecycleProcessor getLifecycleProcessor() throws IllegalStateException {
if (this.lifecycleProcessor == null) {
throw new IllegalStateException(
"LifecycleProcessor not initialized - " +
"call 'refresh' before invoking lifecycle methods via the context: " +
this);
}
return this.lifecycleProcessor;
}
// DefaultLifecycleProcessor 122
@Override
public void onRefresh() {
startBeans(true);
this.running = true;
}
// DefaultLifecycleProcessor 141
private void startBeans(boolean autoStartupOnly) {
// 1.获取所有的Lifecycle bean
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
// 将Lifecycle bean 按阶段分组,阶段通过实现Phased接口得到
Map<Integer, LifecycleGroup> phases = new TreeMap<>();
lifecycleBeans.forEach((beanName, bean) -> {
/* autoStartupOnly=true代表是ApplicationContext刷新时容器自动启动 autoStartupOnly=false代表是通过显示的调用启动 */
// 3.当autoStartupOnly=false,也就是通过显示的调用启动,会触发全部的Lifecycle;
// 当autoStartupOnly=true,也就是ApplicationContext刷新时容器自动启动,只会触发isAutoStartup方法返回true的SmartLifecycle
if (!autoStartupOnly ||
(
bean instanceof SmartLifecycle &&
((SmartLifecycle) bean).isAutoStartup()
)
) {
// 3.1 获取bean的阶段值(如果没有实现Phased接口,则值为0)
int phase = getPhase(bean);
// 3.2 将bean添加到存放该阶段值的LifecycleGroup
phases.computeIfAbsent(
phase,
// 3.3 如果该阶段值的LifecycleGroup为null,则新建一个
p -> new LifecycleGroup(phase,
this.timeoutPerShutdownPhase,
lifecycleBeans,
autoStartupOnly)
).add(beanName, bean);
}
});
// 4.如果phases不为空
if (!phases.isEmpty()) {
// 4.1 调用LifecycleGroup中的所有Lifecycle的start方法
phases.values().forEach(LifecycleGroup::start);
}
}
这边还引入了 Phased
接口,这个接口类似于 Ordered
接口,只有一个方法用于返回一个 “阶段值”
,范围为 Integer.MIN_VALUE ~ Integer.MAX_VALUE
。在启动过程,“阶段值” 小的会被优先调用,而在关闭过程,“阶段值” 大的会被优先调用。
publishEvent()
我们一起来看 finishRefresh()
代码块的 4
中。
当完成ApplicationContext
容器刷新时,Spring
通过事件发布机制发布ContextRefreshedEvent
事件。以保证对应的***可以做进一步的逻辑处理。
Spring的publish-event使用的是监听者模式。
@Override
public void publishEvent(ApplicationEvent event) {
publishEvent(event, null);
}
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
Assert.notNull(event, "Event must not be null");
// Decorate event as an ApplicationEvent if necessary
// 1. 如果是一个ApplicationEvent,就强转,如果不是的话,包装成一个PayloadApplicationEvent
ApplicationEvent applicationEvent;
if (event instanceof ApplicationEvent) {
applicationEvent = (ApplicationEvent) event;
}
else {
applicationEvent = new PayloadApplicationEvent<>(this, event);
if (eventType == null) {
// 包装成一个PayloadApplicationEvent,并获取实际的带泛型的事件类型
// 比如PayloadApplicationEvent<MyEvent>
eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
}
}
// Multicast right now if possible - or lazily once the multicaster is initialized
if (this.earlyApplicationEvents != null) {
this.earlyApplicationEvents.add(applicationEvent);
}
else {
// 2. 使用事件广播器广播事件到相应的***
// 这里就是之前在initApplicationEventMulticaster初始化的事件广播器
// 还有之前在registerListeners方法中注册的***
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}
// Publish event via parent context as well...
// 3. 如果当前容易存在父容器,父容器也要发布事件
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext) {
((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
}
else {
this.parent.publishEvent(event);
}
}
}
multicastEvent()
我们一起来看 publishEvent()
代码块的 2
中。
它是如何使用事件广播器广播事件到相应的***的。
// SimpleApplicationEventMulticaster 135
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor();
// 1. getApplicationListeners:返回与给定事件类型匹配的应用***集合
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
// 2. 返回此广播器的当前任务执行程序
if (executor != null) {
// 3.1 executor不为null,则使用executor调用***
executor.execute(() -> invokeListener(listener, event));
}
else {
// 3.2 否则,直接调用***
invokeListener(listener, event);
}
}
}
可以发现,在通知监听者的时候,会去检查ApplicationEventMulticaster
对象中是否配置了 Executor
执行器,如果配置了的话,会将 invokeListener(listener, event)
封装成一个线程可执行任务,然后给执行器执行。
invokeListener()
我们一起来看 invokeListener()
代码块的 3.1
和 3.2
中。都是在 SimpleApplicationEventMulticaster
中实现的。
调用***的方法。
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
// 1. 返回此广播器的当前错误处理程序
ErrorHandler errorHandler = getErrorHandler();
if (errorHandler != null) {
try {
// 2.1 如果errorHandler不为null,则使用带错误处理的方式调用给定的***
doInvokeListener(listener, event);
}
catch (Throwable err) {
errorHandler.handleError(err);
}
}
else {
// 2.2 否则,直接调用调用给定的***
doInvokeListener(listener, event);
}
}
@SuppressWarnings({
"rawtypes", "unchecked"})
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
// 触发***的onApplicationEvent方法,参数为给定的事件
listener.onApplicationEvent(event);
}
catch (ClassCastException ex) {
String msg = ex.getMessage();
if (msg == null || matchesClassCastMessage(msg, event.getClass()) ||
(event instanceof PayloadApplicationEvent &&
matchesClassCastMessage(msg, ((PayloadApplicationEvent) event).getPayload().getClass()))) {
// Possibly a lambda-defined listener which we could not resolve the generic event type for
// -> let's suppress the exception.
Log loggerToUse = this.lazyLogger;
if (loggerToUse == null) {
loggerToUse = LogFactory.getLog(getClass());
this.lazyLogger = loggerToUse;
}
if (loggerToUse.isTraceEnabled()) {
loggerToUse.trace("Non-matching event type for listener: " + listener, ex);
}
}
else {
throw ex;
}
}
}
自定义广播器的实现
我们可以自定义一个 ApplicationEventMulticaster
:
//需要注意的是,我们的名字一定要叫applicationEventMulticaster,否则不生效,回头看下源码就明白了
@Component("applicationEventMulticaster")
public class MyMulticaster extends SimpleApplicationEventMulticaster {
@Override
protected Executor getTaskExecutor() {
// 这里可以按实际需求进行线程池的配置
return new SimpleAsyncTaskExecutor();
}
// 这个方法主要配置错误处理,默认只会打一个警告级别的日志
@Override
protected ErrorHandler getErrorHandler() {
return (() -> {
System.out.println("出错了");
});
}
}
通过上面的配置后,我们所有的 publish-event
都会通过异步的机制去执行,但是我们想一个问题,有时候我们不想异步呢?一部分我们想同步,一部分想异步,这个时候怎么做呢?我们可以通过下面这种方式:
- 配置类上加注解
@EnableAsync
- 执行的方法上加注解
@Async
// 执行的方法上加@Async注解
@EventListener
@Async
public void on(MySecondEvent event) throws Exception {
// ......
}
这样通过aop的方式,会将我们的方法采用异步的方式进行执行。我们没有配置线程池的时候可能会报错:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.core.task.TaskExecutor' available
不过我们方法还是会异步执行,这主要是下面这段代码:
protected Executor getDefaultExecutor(@Nullable BeanFactory beanFactory) {
if (beanFactory != null) {
try {
// 在这里会抛出一个NoSuchBeanDefinitionException
return beanFactory.getBean(TaskExecutor.class);
}
catch (NoUniqueBeanDefinitionException ex) {
logger.debug("Could not find unique TaskExecutor bean", ex);
try {
return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
}
catch (NoSuchBeanDefinitionException ex2) {
if (logger.isInfoEnabled()) {
logger.info("More than one TaskExecutor bean found within the context, and none is named " +
"'taskExecutor'. Mark one of them as primary or name it 'taskExecutor' (possibly " +
"as an alias) in order to use it for async processing: " + ex.getBeanNamesFound());
}
}
}
// 这里被捕获
catch (NoSuchBeanDefinitionException ex) {
logger.debug("Could not find default TaskExecutor bean", ex);
try {
// 我们也没有定义一个名字是DEFAULT_TASK_EXECUTOR_BEAN_NAME = "taskExecutor"
// 的线程池
return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
}
catch (NoSuchBeanDefinitionException ex2) {
logger.info("No task executor bean found for async processing: " +
"no bean of type TaskExecutor and no bean named 'taskExecutor' either");
}
// Giving up -> either using local default executor or none at all...
}
}
// 最后会返回一个null
return null;
}
@Override
@Nullable
// 最后会返回一个SimpleAsyncTaskExecutor
protected Executor getDefaultExecutor(@Nullable BeanFactory beanFactory) {
Executor defaultExecutor = super.getDefaultExecutor(beanFactory);
return (defaultExecutor != null ? defaultExecutor : new SimpleAsyncTaskExecutor());
}
自定义***的实现
如果我们想在 Spring IoC 容器构建完毕之后进行一些逻辑,就可以通过***来实现。
例如,创建一个自定义***,实现 ApplicationListener
接口,监听 ContextRefreshedEvent
(上下文刷新完毕事件),并且将该***注册到 Spring IoC 容器即可。
@Component("myRefreshedListener")
public class MyRefreshedListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
// ...
}
}
这样,当 Spring 执行到 finishRefresh
方法时,就会将 ContextRefreshedEvent
事件推送到 MyRefreshedListener
中。
跟 ContextRefreshedEvent
相似的还有:ContextStartedEvent
、ContextClosedEvent
、ContextStoppedEvent
,有兴趣的可以自己看看这几个事件的使用场景。
当然,我们也可以自定义监听事件,只需要继承 ApplicationContextEvent
抽象类即可。