Spring 中最核心的方法就是 refresh,负责完成 Bean 注册、Bean 实例化、AOP

1. refresh()

ClassPathXmlApplicationContext # ClassPathXmlApplicationContext

public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {

		super(parent);
		setConfigLocations(configLocations);
		if (refresh) {
			refresh();
		}
	}
AbstractApplicationContext # refresh

public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

		// 刷新上下文环境,(如设置启动时间,对系统属性、环境变量进行准备、验证),为容器初始化做准备
		prepareRefresh();

		/**
		 * 创建 BeanFactory 对象,并解析 XML。经过这个函数后,ApplicationContext 就拥有了 BeanFactory 的全部功能。
		 * 在 xml 解析时,会封装 xml 标签成 BeanDefinition 对象。包括 2 类标签解析:
		 * 		1. 默认标签解析:bean、import、alias、beans
		 * 		2. 自定义标签解析,如:<context:component-scan base-package="com.xmustang.bean" />
		 */
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// 给 beanFactory 设置一些属性值,如增加对 SpEL 支持
		prepareBeanFactory(beanFactory);

		try {
			// 供子类覆写
			postProcessBeanFactory(beanFactory);

			StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
			
			// 实例化所有实现了 BeanDefinitionRegistryPostProcessor、BeanFactoryPostProcessor 接口的类,
			// 并完成这两个接口中的方法调用
			invokeBeanFactoryPostProcessors(beanFactory);

			// 实例化所有实现了 BeanPostProcessor 接口的类,并加入到 BeanFactory 中,
			// 这些 BeanPostProcessor 在 bean 创建过程中调用
			registerBeanPostProcessors(beanFactory);
			beanPostProcess.end();

			// 初始化 MessageSource,主要是完成国际化处理
			initMessageSource();

			// 初始化事件管理类
			initApplicationEventMulticaster();

			// 供子类覆写
			onRefresh();

			// 在所有 Bean 中查找 ApplicationListener,注册到事件管理类中
			registerListeners();

			/*
			 * 这个方法完成包括:
			 * 1. bean 实例化(包含创建对象、IOC)
			 * 2. AOP
			 */
			finishBeanFactoryInitialization(beanFactory);

			// 完成刷新过程,通知生命周期处理器 lifecycleProcessor 刷新过程,同时发出 ContextRefreshEvent 通知
			// 在 Spring 中还提供了 Lifecycle 接口,Lifecycle 中包含 start/stop 方法,实现此接口后,
			// Spring 会保证在启动时调用其 start 方法开始生命周期,在关闭时调用其 stop 方法结束生命周期,
			// 通常用来配置后台程序,在启动后一直运行(如对 MQ 进行轮询等)
			finishRefresh();
		} catch (BeansException ex) {
			if (logger.isWarnEnabled()) {
				logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex);
			}

			// Destroy already created singletons to avoid dangling resources.
			destroyBeans();

			// Reset 'active' flag.
			cancelRefresh(ex);

			// Propagate exception to caller.
			throw ex;
		} finally {
			// Reset common introspection caches in Spring's core, since we might not ever need metadata for singleton beans anymore...
			resetCommonCaches();
			contextRefresh.end();
		}
	}
}

以下讲解 refresh 中不是太重要的方法,重要的方法留给后续分章节讲解:

2. prepareRefresh()

AbstractApplicationContext # prepareRefresh

protected void prepareRefresh() {
	// Switch to active.
	this.startupDate = System.currentTimeMillis();
	this.closed.set(false);
	this.active.set(true);

	if (logger.isDebugEnabled()) {
		if (logger.isTraceEnabled()) {
			logger.trace("Refreshing " + this);
		} else {
			logger.debug("Refreshing " + getDisplayName());
		}
	}

	// 留给子类覆盖,用户可根据自身的需要重写 initPropertySources(),并在方法中进行个性化的属性处理及设置
	initPropertySources();

	// 验证需要的属性文件是否都已经放入环境中
	getEnvironment().validateRequiredProperties();

	// Store pre-refresh ApplicationListeners...
	if (this.earlyApplicationListeners == null) {
		this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
	} else {
		// Reset local application listeners to pre-refresh state.
		this.applicationListeners.clear();
		this.applicationListeners.addAll(this.earlyApplicationListeners);
	}

	// Allow for the collection of early ApplicationEvents,
	// to be published once the multicaster is available...
	this.earlyApplicationEvents = new LinkedHashSet<>();
}

3. prepareBeanFactory(beanFactory)

/**
 * 主要进行下面几个方面的扩展:
 * 1. 增加对 SpEL 语言的支持
 * 2. 增加对属性编辑器的支持
 * 3. 增加对一些内置类,如 EnvironmentAware、MessageSourceAware 信息注入
 * 4. 设置依赖功能可忽略的接口
 * 5. 设置一些固定依赖的属性
 * 6. 增加 AspectJ 的支持
 * 7. 将相关环境变量及属性注册为单例模式
 */
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	
	// 设置 BeanFactory 的 classLoader 为当前 context 的 classLoader
	beanFactory.setBeanClassLoader(getClassLoader());
	if (!shouldIgnoreSpel) {
		// 设置 beanFactory 的表达式语言处理器,Spring 3 增加了表达式语言的支持
		// 默认可使用 #{bean.xxx} 的形式来调用相关属性值
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
	}
	// 为 BeanFactory 增加了一个默认的 propertyEditor,这个主要是对 bean 的属性等设置管理的一个工具
	beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

	// 添加 BeanPostProcessor
	beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
	// 设置几个忽略自动装配的接口。
	// Spring 将 ApplicationContextAwareProcessor 注册后,
	// 在 invokeAwareInterfaces 中间接调用的 Aware 类已经不是普通的 bean 了,
	// 如 ResourceLoaderAware、ApplicationEventPublisherAware 等,当然需要在做 bean 依赖注入时忽略它们。
	beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
	beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
	beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
	beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
	beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
	beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
	beanFactory.ignoreDependencyInterface(ApplicationStartup.class);

	// 设置几个自动装配的特殊规则
	beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
	beanFactory.registerResolvableDependency(ResourceLoader.class, this);
	beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
	beanFactory.registerResolvableDependency(ApplicationContext.class, this);

	// Register early post-processor for detecting inner beans as ApplicationListeners.
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

	// 增加对 AspectJ 的支持
	if (!IN_NATIVE_IMAGE && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
		beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
		// Set a temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
	}

	// 添加默认的系统环境 bean
	if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
		beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
	}
	if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
		beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
	}
	if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
		beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
	}
	if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
		beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
	}
}

4. initMessageSource()

AbstractApplicationContext # initMessageSource

/**
 * Spring 使用硬编码的方式硬性规定了自定义资源文件 beanName 必须为 messageSource
 */
protected void initMessageSource() {
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
		// 如果在配置中已经配置了 messageSource,那么将 messageSource 提取并记录在 this.messageSource 中
		this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
		// Make MessageSource aware of parent MessageSource.
		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.
				hms.setParentMessageSource(getInternalParentMessageSource());
			}
		}
		if (logger.isTraceEnabled()) {
			logger.trace("Using MessageSource [" + this.messageSource + "]");
		}
	} else {
		// Use empty MessageSource to be able to accept getMessage calls.
		// 如果用户并没有定义配置文件,那么使用 DelegatingMessageSource
		DelegatingMessageSource dms = new DelegatingMessageSource();
		dms.setParentMessageSource(getInternalParentMessageSource());
		this.messageSource = dms;
		beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
		if (logger.isTraceEnabled()) {
			logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
		}
	}
}

5. Spring 事件

Spring 事件使用的是观察者设计模式,观察者设计模式用于异步解耦。
Spring 提供了下面 5 种标准事件:

  1. ContextRefreshedEvent:在调用 ConfigurableApplicationContext 接口中的 refresh() 触发
  2. ContextStartedEvent:在调用 ConfigurableApplicationContext 接口中的 start() 触发
  3. ContextStoppedEvent:在调用 ConfigurableApplicationContext 接口中的 stop() 触发
  4. ContextClosedEvent:当 ApplicationContext 被关闭时触发该事件。容器被关闭时,其管理的所有单例 Bean 都被销毁
  5. RequestHandlerEvent:在 Web 应用中,当一个 Http 请求结束时触发该事件

5.1 事件示例

public class MyApplicationEvent extends ApplicationEvent {
    public MyApplicationEvent(Object source) {
        super(source);
    }
}

@Component
public class MyEventListener implements ApplicationListener {
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof MyApplicationEvent) {
            System.out.println("receive MyApplicationEvent:" + event.getSource());
        }
        if (event instanceof ContextRefreshedEvent) {
            System.out.println("receive ContextRefreshedEvent:" + event.getSource());
        }
        if (event instanceof ContextStartedEvent) {
            System.out.println("receive ContextStartedEvent:" + event.getSource());
        }
        if (event instanceof ContextStoppedEvent) {
            System.out.println("receive ContextStoppedEvent:" + event.getSource());
        }
        if (event instanceof ContextClosedEvent) {
            System.out.println("receive ContextClosedEvent:" + event.getSource());
        }
        if (event instanceof RequestHandledEvent) {
            System.out.println("receive RequestHandledEvent:" + event.getSource());
        }
    }
}

@Component("publishEvent")
public class MyPublishEvent implements ApplicationEventPublisherAware {
    private ApplicationEventPublisher applicationEventPublisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    public void publish(String msg) {
        applicationEventPublisher.publishEvent(new MyApplicationEvent(msg));
    }
}
<!-- Spring 事件 begin -->
<context:component-scan base-package="com.mustang.event"/>
<!-- Spring 事件 end -->

测试:

public class Main {
   public static void main(String[] args) {
       ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");

       MyPublishEvent myPublishEvent = (MyPublishEvent) context.getBean("publishEvent");
       // receive MyApplicationEvent:myEvent
       myPublishEvent.publish("myEvent");
       // receive ContextRefreshedEvent:org.springframework.context.support.ClassPathXmlApplicationContext@13969fbe, started on Wed Jun 23 16:56:06 CST 2021
       context.refresh();
       // receive ContextStartedEvent:org.springframework.context.support.ClassPathXmlApplicationContext@13969fbe, started on Wed Jun 23 16:56:06 CST 2021
       context.start();
       // receive ContextStoppedEvent:org.springframework.context.support.ClassPathXmlApplicationContext@13969fbe, started on Wed Jun 23 16:56:06 CST 2021
       context.stop();
       // receive ContextClosedEvent:org.springframework.context.support.ClassPathXmlApplicationContext@13969fbe, started on Wed Jun 23 16:56:06 CST 2021
       context.close();
   }
}

5.2 initApplicationEventMulticaster()

AbstractApplicationContext # initApplicationEventMulticaster

protected void initApplicationEventMulticaster() {
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	// 如果用户没有自定义事件广播器,那么使用默认的 ApplicationEventMulticaster
	if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
		this.applicationEventMulticaster =
				beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
		if (logger.isTraceEnabled()) {
			logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
		}
	} else {// 如果用户自定义了事件广播器,那么使用用户自定义的事件广播器
		this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
		beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
		if (logger.isTraceEnabled()) {
			logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " + "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
		}
	}
}

5.3 registerListeners()

AbstractApplicationContext # registerListeners

protected void registerListeners() {
	// 硬编码方式注册的监听器处理
	for (ApplicationListener<?> listener : getApplicationListeners()) {
		getApplicationEventMulticaster().addApplicationListener(listener);
	}

	// 配置文件注册的监听器处理:获取实现了 ApplicationListener 接口的类名称
	String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
	for (String listenerBeanName : listenerBeanNames) {
		getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
	}

	// Publish early application events now that we finally have a multicaster...
	Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
	this.earlyApplicationEvents = null;
	if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
		for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
			// 多播事件,事件执行
			getApplicationEventMulticaster().multicastEvent(earlyEvent);
		}
	}
}
SimpleApplicationEventMulticaster # multicastEvent

public void multicastEvent(ApplicationEvent event) {
	multicastEvent(event, resolveDefaultEventType(event));
}
SimpleApplicationEventMulticaster # multicastEvent

public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
	ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
	Executor executor = getTaskExecutor();
	// 遍历所有监听器,并使用监听器中的 onApplicationEvent 方法进行监听事件的处理。
	// 对于每个监听器来说,都可以获取到产生的事件,但是否进行处理则由事件监听器来决定:void onApplicationEvent(E event);
	for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
		if (executor != null) {
			executor.execute(() -> invokeListener(listener, event));
		} else {
			invokeListener(listener, event);
		}
	}
}
SimpleApplicationEventMulticaster # invokeListener

protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
	ErrorHandler errorHandler = getErrorHandler();
	if (errorHandler != null) {
		try {
			doInvokeListener(listener, event);
		} catch (Throwable err) {
			errorHandler.handleError(err);
		}
	} else {
		doInvokeListener(listener, event);
	}
}
SimpleApplicationEventMulticaster # doInvokeListener

private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
	try {
		listener.onApplicationEvent(event);
	} catch (ClassCastException ex) {
		String msg = ex.getMessage();
		if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
			// Possibly a lambda-defined listener which we could not resolve the generic event type for
			// -> let's suppress the exception and just log a debug message.
			Log logger = LogFactory.getLog(getClass());
			if (logger.isTraceEnabled()) {
				logger.trace("Non-matching event type for listener: " + listener, ex);
			}
		} else {
			throw ex;
		}
	}
}