Springboot之---强大的Servlet(二)
【摘要】 Spring容器内部工作机制AbstractApplicationContextorg.springframework.context.support.AbstractApplicationContextpackage org.springframework.context.support;/** * 使用模板方法设计模式,需要具体的子类来实现抽象方法。 */public abstract...
Spring容器内部工作机制AbstractApplicationContext
org.springframework.context.support.AbstractApplicationContext
package org.springframework.context.support;
/**
* 使用模板方法设计模式,需要具体的子类来实现抽象方法。
*/
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
/**
* 在此工厂中,国际化消息 MessageSource 的 bean的名称。
* 如果没有提供消息,消息解析将委托给父节点。
* @see MessageSource
*/
public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";
/**
* 在此工厂中,SpringBean 的生命周期LifecycleProcessor 的 bean的名称
* 如果没有提供,则使用DefaultLifecycleProcessor。
* @see org.springframework.context.LifecycleProcessor
* @see org.springframework.context.support.DefaultLifecycleProcessor
*/
public static final String LIFECYCLE_PROCESSOR_BEAN_NAME = "lifecycleProcessor";
/**
* 在此工厂中,应用事件多路广播器 的 bean的名称。
* 如果没有提供,则使用默认的simpleapplicationeventmultiaster。
* @see org.springframework.context.event.ApplicationEventMulticaster
* @see org.springframework.context.event.SimpleApplicationEventMulticaster
*/
public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
static {
ContextClosedEvent.class.getName();
}
/** 这个类使用的logger。可用于子类。 */
protected final Log logger = LogFactory.getLog(getClass());
/** 此上下文的唯一id(如果有的话)。 */
private String id = ObjectUtils.identityToString(this);
/** 显示名称 */
private String displayName = ObjectUtils.identityToString(this);
/** 父上下文。 */
@Nullable
private ApplicationContext parent;
/** 此上下文使用的环境。 */
@Nullable
private ConfigurableEnvironment environment;
/** 应用于刷新的 BeanFactoryPostProcessors */
private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();
/** 此上下文启动时的系统时间(毫秒)。 */
private long startupDate;
/** 指示此上下文当前是否处于活动状态的标志。 */
private final AtomicBoolean active = new AtomicBoolean();
/** 指示此上下文是否已关闭的标志。 */
private final AtomicBoolean closed = new AtomicBoolean();
/** 用于"刷新" 和 "销毁" 时的同步监视器(浅显是说就是当做锁) */
private final Object startupShutdownMonitor = new Object();
/** 如果已注册,则引用JVM关闭链接。 */
@Nullable
private Thread shutdownHook;
/** 此上下文使用的 ResourcePatternResolver 资源模式解析器 */
private ResourcePatternResolver resourcePatternResolver;
/** LifecycleProcessor 生命周期处理器,用于在此上下文中管理bean的生命周期。 */
@Nullable
private LifecycleProcessor lifecycleProcessor;
/** 我们将这个接口的实现委托给 MessageSource */
@Nullable
private MessageSource messageSource;
/** 事件发布所使用的助手类。 */
@Nullable
private ApplicationEventMulticaster applicationEventMulticaster;
/** 静态的、指定的 listeners 监听器Set集合. */
private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
/** 早期发布的 ApplicationEvents 应用事件Set集合. */
@Nullable
private Set<ApplicationEvent> earlyApplicationEvents;
/** 创建一个没有父元素的新的AbstractApplicationContext。 */
public AbstractApplicationContext() {
this.resourcePatternResolver = getResourcePatternResolver();
}
/** 使用给定的父上下文来创建一个新的AbstractApplicationContext。 */
public AbstractApplicationContext(@Nullable ApplicationContext parent) {
this();
setParent(parent);
}
//---------------------------------------------------------------------
// ApplicationContext接口的实现
//---------------------------------------------------------------------
/**
* 设置此应用程序上下文的惟一id。
* 默认值是上下文实例的对象id,或者上下文bean的名称(如果上下文本身定义为bean的话)。
* @param id 上下文的唯一id
*/
@Override
public void setId(String id) {
this.id = id;
}
/** 获取此应用程序上下文的id。 */
@Override
public String getId() {
return this.id;
}
@Override
public String getApplicationName() {
return "";
}
/**
* 为这个上下文设置一个(显示)名称。
* 通常在具体上下文实现的初始化过程中完成。
* 默认值是上下文实例的对象id。
*/
public void setDisplayName(String displayName) {
// 设置显示的上下文名称不能为空
Assert.hasLength(displayName, "Display name must not be empty");
this.displayName = displayName;
}
/**
* 获取并返回此应用上下文的展示名称
* @return 此应用上下文的展示名称(非null)
*/
@Override
public String getDisplayName() {
return this.displayName;
}
/**
* 返回父上下文,如果没有父上下文,则返回 null。
* (返回null意为着,此应用上下文是整个应用上下文体系的根上下文)。
*/
@Override
@Nullable
public ApplicationContext getParent() {
return this.parent;
}
/**
* 为这个应用程序上下文设置 Environment 环境
* 默认值由 createEnvironment()方法决定。
* 用这个方法替换默认值不是唯一选择,还可通过 getEnvironment() 方法进行配置。
* 但不管在哪一种情况下,这些修改都应该在 refresh() 方法前执行。
* @see org.springframework.context.support.AbstractApplicationContext#createEnvironment
*/
@Override
public void setEnvironment(ConfigurableEnvironment environment) {
this.environment = environment;
}
/**
* 获取并返回此应用上下文的环境,如果为null,则通过 createEnvironment() 方法进行创建并返回。
*/
@Override
public ConfigurableEnvironment getEnvironment() {
if (this.environment == null) {
this.environment = createEnvironment();
}
return this.environment;
}
/**
* 创建并返回新的StandardEnvironment 标准环境。
* 子类可以重写此方法,以便提供自定义 ConfigurableEnvironment 可配置环境的实现。
*/
protected ConfigurableEnvironment createEnvironment() {
return new StandardEnvironment();
}
/**
* 如果此应用上下文已经可用,则将此上下文的内部bean工厂返回为AutowireCapableBeanFactory。
* @see #getBeanFactory()
*/
@Override
public AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException {
return getBeanFactory();
}
/** 在首次加载此上下文时返回时间戳(ms)。 */
@Override
public long getStartupDate() {
return this.startupDate;
}
/**
* 将给定的事件发布给所有监听器。
* 注意:监听器在 MessageSource 之后初始化,以便能够在监听器实现中访问它。
* 因此,MessageSource 实现不能发布事件。要发布的事件(可能是特定于应用程序或标准框架事件)
*/
@Override
public void publishEvent(ApplicationEvent event) {
publishEvent(event, null);
}
/**
* 将给定的事件发布给所有监听器。
* 注意:监听器在 MessageSource 之后初始化,以便能够在监听器实现中访问它。
* 因此,MessageSource 实现不能发布事件。
* 要发布的事件(可能是 ApplicationEvent 或要转换为 PayloadApplicationEvent 的有效负载对象)
*/
@Override
public void publishEvent(Object event) {
publishEvent(event, null);
}
/**
* 将给定的事件发布给所有监听器。
* @param event 要发布的事件(可能是 ApplicationEvent 或要转换为 PayloadApplicationEvent 的有效负载对象)
* @param eventType 可解析的事件类型(如果已知)(前面的文章已经提到过)
* @since 4.2
*/
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
Assert.notNull(event, "Event must not be null");
// 必要时将事件装饰为 ApplicationEvent
ApplicationEvent applicationEvent;
if (event instanceof ApplicationEvent) {
applicationEvent = (ApplicationEvent) event;
}
else {
applicationEvent = new PayloadApplicationEvent<>(this, event);
if (eventType == null) {
eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType();
}
}
// 如果可能的话,现在就进行多播——或者在初始化多播器之后延迟
if (this.earlyApplicationEvents != null) {
this.earlyApplicationEvents.add(applicationEvent);
}
else {
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}
// 通过父上下文发布事件…
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext) {
((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
}
else {
this.parent.publishEvent(event);
}
}
}
/**
* 返回上下文使用的内部 ApplicationEventMulticaster 应用事件多路广播器
* @return 上下文使用的内部 ApplicationEventMulticaster 应用事件多路广播器(从不为null)
* @throws IllegalStateException 如果上下文尚未初始化
*/
ApplicationEventMulticaster getApplicationEventMulticaster() throws IllegalStateException {
if (this.applicationEventMulticaster == null) {
throw new IllegalStateException("ApplicationEventMulticaster not initialized - " +
"call 'refresh' before multicasting events via the context: " + this);
}
return this.applicationEventMulticaster;
}
/**
* 返回上下文使用的内部生命周期处理器。
* @return 内部生命周期处理器。 (从不为null)
* @throws IllegalStateException 如果上下文尚未初始化
*/
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;
}
/**
* 返回此 ResourcePatternResolver资源模式解析器,
* 用于将多个资源的位置按照模式解析到资源实例中。
* 默认是org.springframework.core.io.support.PathMatchingResourcePatternResolver。
* 支持ant风格的位置模式。
* 可以在子类中重写,用于扩展解析策略,例如在web环境中。在需要解决位置模式时不要调用此函数。
* 相反,调用上下文的getResources方法,它将委托给ResourcePatternResolver。
* @return 此应用上下文的 ResourcePatternResolver 资源模式解析器
* @see #getResources
* @see org.springframework.core.io.support.PathMatchingResourcePatternResolver
*/
protected ResourcePatternResolver getResourcePatternResolver() {
return new PathMatchingResourcePatternResolver(this);
}
//---------------------------------------------------------------------
// ConfigurableApplicationContext接口的实现
//---------------------------------------------------------------------
/**
* 设置此应用程序上下文的父上下文。
* 父级ApplicationContext#getEnvironment()环境是
* ConfigurableEnvironment#merge(ConfigurableEnvironment),如果父级非null,
* 并且它的环境是ConfigurableEnvironment的实例,那么它就会与这个(子级)应用程序上下文环境合并
* @see ConfigurableEnvironment#merge(ConfigurableEnvironment)
*/
@Override
public void setParent(@Nullable ApplicationContext parent) {
this.parent = parent;
if (parent != null) {
Environment parentEnvironment = parent.getEnvironment();
if (parentEnvironment instanceof ConfigurableEnvironment) {
getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);
}
}
}
/** 添加Bean工厂后置处理器 */
@Override
public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
this.beanFactoryPostProcessors.add(postProcessor);
}
/**
* 返回将应用到内部BeanFactory的BeanFactoryPostProcessors列表。
*/
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
return this.beanFactoryPostProcessors;
}
/** 添加应用上下文监听器 */
@Override
public void addApplicationListener(ApplicationListener<?> listener) {
Assert.notNull(listener, "ApplicationListener must not be null");
if (this.applicationEventMulticaster != null) {
this.applicationEventMulticaster.addApplicationListener(listener);
}
this.applicationListeners.add(listener);
}
/**
* 返回静态指定的ApplicationListeners集合.
*/
public Collection<ApplicationListener<?>> getApplicationListeners() {
return this.applicationListeners;
}
/**
* 加载或刷新一个持久化的配置,可能是XML文件、属性文件或关系数据库模式。
* 由于这是一种启动方法,如果失败,应该销毁已经创建的单例,以避免悬空资源。
* 换句话说,在调用该方法之后,要么全部实例化,要么完全不实例化。
* @throws 如果bean工厂无法初始化,则抛出 BeansException 异常
* @throws 如果已经初始化且不支持多次刷新,则会抛出 IllegalStateException 异常
*/
@Override
public void refresh() throws BeansException, IllegalStateException {
// 加载或刷新配置前的同步处理
synchronized (this.startupShutdownMonitor) {
// 为刷新而准备此上下文
prepareRefresh();
// 告诉子类去刷新内部bean工厂。
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 准备好bean工厂,以便在此上下文中使用。
prepareBeanFactory(beanFactory);
try {
// 允许在上下文子类中对bean工厂进行后置处理。
postProcessBeanFactory(beanFactory);
// 调用在上下文中注册为bean的工厂处理器。
invokeBeanFactoryPostProcessors(beanFactory);
// 注册拦截bean创建的bean处理器。
registerBeanPostProcessors(beanFactory);
// 初始化此上下文的 message resource 消息资源。
initMessageSource();
// 为这个上下文初始化事件多路广播器。
initApplicationEventMulticaster();
// 初始化特定上下文子类中的其他特殊bean。
onRefresh();
// 注册监听器(检查监听器的bean并注册它们)。
registerListeners();
// 实例化所有剩余的(非 lazy-init 懒初始化的)单例。
finishBeanFactoryInitialization(beanFactory);
// 最后一步: 发布相应的事件。
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁已经创建的单例,以避免悬空资源。
destroyBeans();
// 重置 'active' 表示.
cancelRefresh(ex);
// 将异常传播给调用者。
throw ex;
}
finally {
// 重置Spring内核中的共用的缓存,因为我们可能再也不需要单例bean的元数据了……
resetCommonCaches();
}
}
}
/**
* 准备这个上下文来刷新、设置它的启动日期和活动标志以及执行属性源的任何初始化。
*/
protected void prepareRefresh() {
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();
// 验证标记为必需的所有属性是否可解析
// 请参考 ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();
// 允许在多路广播器可用时,就会发布初期 ApplicationEvents 应用事件的集合
this.earlyApplicationEvents = new LinkedHashSet<>();
}
/**
* 用实际实例替换任何存根属性源。
* @see org.springframework.core.env.PropertySource.StubPropertySource
* @see org.springframework.web.context.support.WebApplicationContextUtils#initServletPropertySources
*/
protected void initPropertySources() {
// 对于子类:默认情况下不执行任何操作。
}
/**
* 通知此上下文的子类去加载或刷新其内在的bean工厂
* @return 新的bean工厂实例
* @see #refreshBeanFactory()
* @see #getBeanFactory()
*/
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
/**
* 配置工厂的标准上下文的特征属性,
* 例如上下文的ClassLoader类加载器和post-processors后置处理器。
* @param beanFactory 要配置的bean工厂
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 告诉内部bean工厂使用上下文的类加载器等。
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 使用上下文回调配置bean工厂。
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
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接口没有注册为可解析的类型。
// MessageSource注册(并发现自动)为一个bean。
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 注册早期后置处理器,用于检测内部bean作为应用程序监听器。
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 如何找到一个LoadTimeWeaver,那么就准备将后置处理器“织入”bean工厂
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// 为类型匹配设置临时类加载器。
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 注册默认environment环境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());
}
}
/**
* 在标准初始化后修改应用程序上下文的内部bean工厂。
* 所有bean定义都将被加载,但是没有bean会被实例化。
* 这允许在某些应用上下文实现中注册特殊的BeanPostProcessors等。
* @param beanFactory 应用环境下的Bean工厂
*/
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
/**
* 实例化并调用所有已注册的BeanFactoryPostProcessor 的 bean,如果已给出顺序,请按照顺序。
* 必须在单实例实例化之前调用。
*/
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// 如何找到一个LoadTimeWeaver,那么就准备将后置处理器“织入”bean工厂
// (例如,一个 @Bean 方法通过ConfigurationClassPostProcessor来注册)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
/**
* BeanPostProcessor 的 bean,如果给出显式顺序,请按照顺序。
* 必须在应用程序bean的任何实例化之前调用。
*/
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
/**
* 初始化MessageSource。
* 如果在此上下文中未定义国际化资源,则使用父上下文的国际化资源。
*/
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// 使用此上下文的 MessageSource 知道父上下文的 MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// 如果没有已注册的父MessageSource,则只将父上下文设置为父MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isTraceEnabled()) {
logger.trace("Using MessageSource [" + this.messageSource + "]");
}
}
else {
// 使用空MessageSource可以接受getMessage方法的调用。
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 + "]");
}
}
}
/**
* 初始化ApplicationEventMulticaster。
* 如果在上下文中没有定义,则使用SimpleApplicationEventMulticaster。
* @see org.springframework.context.event.SimpleApplicationEventMulticaster
*/
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
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() + "]");
}
}
}
```
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)