1 启动入口
1.1 ApplicationContext
一般情况下,Spring的启动入口为new ClassPathXmlApplicationContext(configLocations);或new FileSystemXmlApplicationContext(configLocations)
org.springframework.context.ApplicationContext的向下子类类继承关系如下:
ConfigurableApplicationContext (org.springframework.context)
AbstractApplicationContext (org.springframework.context.support)
GenericApplicationContext (org.springframework.context.support)
GenericXmlApplicationContext (org.springframework.context.support)
StaticApplicationContext (org.springframework.context.support)
ResourceAdapterApplicationContext (org.springframework.jca.context)
GenericGroovyApplicationContext (org.springframework.context.support)
AnnotationConfigApplicationContext (org.springframework.context.annotation)
AbstractRefreshableApplicationContext (org.springframework.context.support)
AbstractRefreshableConfigApplicationContext (org.springframework.context.support)
AbstractXmlApplicationContext (org.springframework.context.support)
FileSystemXmlApplicationContext (org.springframework.context.support)
ClassPathXmlApplicationContext (org.springframework.context.support)
向上的父类类继承关系如下:
EnvironmentCapable (org.springframework.core.env)
ListableBeanFactory (org.springframework.beans.factory)
BeanFactory (org.springframework.beans.factory)
HierarchicalBeanFactory (org.springframework.beans.factory)
BeanFactory (org.springframework.beans.factory)
MessageSource (org.springframework.context)
ApplicationEventPublisher (org.springframework.context)
ResourcePatternResolver (org.springframework.core.io.support)
ResourceLoader (org.springframework.core.io)
1.1.1 ApplicationContext接口分析
通过分析类实现的接口,下面分析每个接口的职责范围。
1.1.1.1 EnvironmentCapable
org.springframework.core.env.EnvironmentCapable的实现如下:
public interface EnvironmentCapable {
// 展示一个Component包含的组件,并将该组件暴露出来
Environment getEnvironment();
}
1.1.1.2 BeanFactory
org.springframework.beans.factory.BeanFactory为Spring IOC的核心接口,实现从IOC查询Bean的接口,实现如下:
public interface BeanFactory {
// 用于解引用{@link FactoryBean}实例,并将其与FactoryBean<i>创建的bean区分开来。例如,如果名为{@code myJndiObject}的bean是一个FactoryBean,则获取{@code &myJndiObject}将返回工厂,而不是工厂返回的实例。
String FACTORY_BEAN_PREFIX = "&";
// 根据Bean名称查询Bean对象
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
// args为指定的构造Bean的参数
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
// 根据指定的类型,获取ObjectProvider,对依赖注入进行更加宽松的配置
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
// org.springframework.core.ResolvableType是对Java type类型的封装
<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
boolean containsBean(String name);
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
// 是否是prototype类型,在每次注入或者通过Spring应用上下文获取的时候,都会创建一个新的bean实例
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
@Nullable
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
// 如果判断的是一个FactoryBean,是否允许其触发初始化已获取FactoryBean的类型
@Nullable
Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;
// 获取对应Bean的别名
String[] getAliases(String name);
}
org.springframework.beans.factory.ObjectFactory的接口实现如下:
@FunctionalInterface // 函数式接口
public interface ObjectFactory<T> {
T getObject() throws BeansException; // 返回一个指定类型的Bean
}
org.springframework.beans.factory.ObjectProvider的实现如下:
// 专门为注入点设计的{@link ObjectFactory}的变体,允许编程的可选性和宽松的非唯一性处理。
public interface ObjectProvider<T> extends ObjectFactory<T>, Iterable<T> {
// 根据创建Bean时的参数获取Bean
T getObject(Object... args) throws BeansException;
@Nullable
T getIfAvailable() throws BeansException;
default T getIfAvailable(Supplier<T> defaultSupplier) throws BeansException {
T dependency = getIfAvailable();
return (dependency != null ? dependency : defaultSupplier.get());
}
// 由于是函数式接口,如果可以获取,则使用dependencyConsumer进行消费
default void ifAvailable(Consumer<T> dependencyConsumer) throws BeansException {
T dependency = getIfAvailable();
if (dependency != null) {
dependencyConsumer.accept(dependency);
}
}
@Nullable
T getIfUnique() throws BeansException;
default T getIfUnique(Supplier<T> defaultSupplier) throws BeansException {
T dependency = getIfUnique();
return (dependency != null ? dependency : defaultSupplier.get());
}
default void ifUnique(Consumer<T> dependencyConsumer) throws BeansException {
T dependency = getIfUnique();
if (dependency != null) {
dependencyConsumer.accept(dependency);
}
}
@Override
default Iterator<T> iterator() {
return stream().iterator();
}
default Stream<T> stream() {
throw new UnsupportedOperationException("Multi element access not supported");
}
default Stream<T> orderedStream() {
throw new UnsupportedOperationException("Ordered element access not supported");
}
}
1.1.1.3 ListableBeanFactory
org.springframework.beans.factory.ListableBeanFactory,用于获取IOC中的所有Bean的信息,扩展BeanFactory只能单个获取Bean的能力,实现如下:
public interface ListableBeanFactory extends BeanFactory {
// BeanFactory中是否包含对应的beanName
boolean containsBeanDefinition(String beanName);
// 获取所有定义的Bean数量
int getBeanDefinitionCount();
// 获取所有定义的Bean的名称
String[] getBeanDefinitionNames();
// 根据指定的类型requiredType获取ObjectProvider,allowEagerInit是否允许触发延迟加载的Bean在此时触发加载
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType, boolean allowEagerInit);
<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType, boolean allowEagerInit);
String[] getBeanNamesForType(ResolvableType type);
String[] getBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit);
String[] getBeanNamesForType(@Nullable Class<?> type);
String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
<T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;
<T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
throws BeansException;
// 获取所有使用annotationType类型注解的Bean
String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);
Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;
@Nullable
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
throws NoSuchBeanDefinitionException;
@Nullable
<A extends Annotation> A findAnnotationOnBean(
String beanName, Class<A> annotationType, boolean allowFactoryBeanInit)
throws NoSuchBeanDefinitionException;
}
1.1.1.4 HierarchicalBeanFactory
org.springframework.beans.factory.HierarchicalBeanFactory定义了类的层次关系,实现如下:
public interface HierarchicalBeanFactory extends BeanFactory {
// 获取父BeanFactory
@Nullable
BeanFactory getParentBeanFactory();
// 当前的BeanFactory是否包含Bean,忽略父BeanFactory
boolean containsLocalBean(String name);
}
1.1.1.5 MessageSource
org.springframework.context.MessageSource实现国际化相关的配置读取的操作定义,定义如下:
public interface MessageSource {
@Nullable
String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale);
String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException;
String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
}
1.1.1.6 ApplicationEventPublisher
org.springframework.context.ApplicationEventPublisher定义了Spring事件的操作,为函数式接口,实现如下:
@FunctionalInterface
public interface ApplicationEventPublisher {
// 发布事件
default void publishEvent(ApplicationEvent event) {
publishEvent((Object) event);
}
void publishEvent(Object event);
}
下面分析下ApplicationEvent的实现,org.springframework.context.ApplicationEvent实现如下,其中存储了事件的来源和触发时间:
public abstract class ApplicationEvent extends EventObject {
/** use serialVersionUID from Spring 1.2 for interoperability. */
private static final long serialVersionUID = 7099057708183571937L;
/** System time when the event happened. */
private final long timestamp;
public ApplicationEvent(Object source) {
super(source);
this.timestamp = System.currentTimeMillis();
}
public ApplicationEvent(Object source, Clock clock) {
super(source);
this.timestamp = clock.millis();
}
public final long getTimestamp() {
return this.timestamp;
}
}
1.1.1.7 ResourcePatternResolver
org.springframework.core.io.support.ResourcePatternResolver根据文件通配符获取配置文件地址:
public interface ResourcePatternResolver extends ResourceLoader {
// Pseudo URL prefix for all matching resources from the class path: "classpath*:"
// 类路径下的配置文件伪地址
String CLASSPATH_ALL_URL_PREFIX = "classpath*:";
// locationPattern示例xx**:**/*.xy
Resource[] getResources(String locationPattern) throws IOException;
}
1.1.2 ConfigurableApplicationContext
ConfigurableApplicationContext实现ApplicationContext, Lifecycle, Closeable三个接口。
org.springframework.context.Lifecycle进行生命周期控制,实现如下:
public interface Lifecycle {
// 启动当前的组件
void start();
// 停止当前的组件
void stop();
// 判断当前的组件是否在运行状态
boolean isRunning();
}
1.2 AbstractApplicationContext
AbstractApplicationContext是ApplicationContext的实现模板,虚基类,继承org.springframework.core.io.DefaultResourceLoader接口。
1.2.1 ResourceLoader
org.springframework.core.io.ResourceLoader定义了加载配置资源的策略,实现如下:
public interface ResourceLoader {
/** Pseudo URL prefix for loading from the class path: "classpath:". */
String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;
// 根据指定的路径加载配置文件
Resource getResource(String location);
// 暴露出加载资源文件的ClassLoader
@Nullable
ClassLoader getClassLoader();
}
org.springframework.core.io.DefaultResourceLoader为ResourceLoader的默认实现:
public class DefaultResourceLoader implements ResourceLoader {
@Nullable // 加载配置资源使用的ClassLoader
private ClassLoader classLoader;
private final Set<ProtocolResolver> protocolResolvers = new LinkedHashSet<>(4);
private final Map<Class<?>, Map<Resource, ?>> resourceCaches = new ConcurrentHashMap<>(4);
public DefaultResourceLoader() {
}
public DefaultResourceLoader(@Nullable ClassLoader classLoader) {
this.classLoader = classLoader;
}
public void setClassLoader(@Nullable ClassLoader classLoader) {
this.classLoader = classLoader;
}
@Override
@Nullable
public ClassLoader getClassLoader() {
return (this.classLoader != null ? this.classLoader : ClassUtils.getDefaultClassLoader());
}
// 注册ProtocolResolver
public void addProtocolResolver(ProtocolResolver resolver) {
Assert.notNull(resolver, "ProtocolResolver must not be null");
this.protocolResolvers.add(resolver);
}
public Collection<ProtocolResolver> getProtocolResolvers() {
return this.protocolResolvers;
}
@SuppressWarnings("unchecked")
public <T> Map<Resource, T> getResourceCache(Class<T> valueType) {
return (Map<Resource, T>) this.resourceCaches.computeIfAbsent(valueType, key -> new ConcurrentHashMap<>());
}
public void clearResourceCaches() {
this.resourceCaches.clear();
}
// 解析配置文件
@Override
public Resource getResource(String location) {
Assert.notNull(location, "Location must not be null");
// 如果实现了指定的加载逻辑
for (ProtocolResolver protocolResolver : getProtocolResolvers()) {
Resource resource = protocolResolver.resolve(location, this);
if (resource != null) {
return resource;
}
}
// 以/开头的资源路径示例为/org/springframework/beans/factory/support/security/callbacks.xml
if (location.startsWith("/")) {
return getResourceByPath(location);
}
// org.springframework.core.io.ClassPathResource实现了类路径加载的方式
else if (location.startsWith(CLASSPATH_URL_PREFIX)) {
return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
}
else {
try {
// Try to parse the location as a URL...
URL url = new URL(location);
return (ResourceUtils.isFileURL(url) ? new FileUrlResource(url) : new UrlResource(url));
}
catch (MalformedURLException ex) {
// No URL -> resolve as resource path.
return getResourceByPath(location);
}
}
}
protected Resource getResourceByPath(String path) {
return new ClassPathContextResource(path, getClassLoader());
}
protected static class ClassPathContextResource extends ClassPathResource implements ContextResource {
public ClassPathContextResource(String path, @Nullable ClassLoader classLoader) {
super(path, classLoader);
}
@Override
public String getPathWithinContext() {
return getPath();
}
@Override
public Resource createRelative(String relativePath) {
String pathToUse = StringUtils.applyRelativePath(getPath(), relativePath);
return new ClassPathContextResource(pathToUse, getClassLoader());
}
}
}
org.springframework.core.io.ProtocolResolver定义每一个资源的加载逻辑:
@FunctionalInterface // 函数式接口
public interface ProtocolResolver {
// 使用ResourceLoader获取对应location的资源
@Nullable
Resource resolve(String location, ResourceLoader resourceLoader);
}
1.2.2 AbstractApplicationContext实现分析
org.springframework.context.support.AbstractApplicationContext定义了IOC容器的通用实现,定义如下:
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
// Name of the MessageSource bean in the factory
public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";
// Name of the LifecycleProcessor bean in the factory.
public static final String LIFECYCLE_PROCESSOR_BEAN_NAME = "lifecycleProcessor";
// Name of the ApplicationEventMulticaster bean in the factory.
public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
// 是否忽略Spel表达式
private static final boolean shouldIgnoreSpel = SpringProperties.getFlag("spring.spel.ignore");
static {
// 触发ContextClosedEvent的加载
ContextClosedEvent.class.getName();
}
/** Flag that indicates whether this context is currently active. */
private final AtomicBoolean active = new AtomicBoolean();
/** Flag that indicates whether this context has been closed already. */
private final AtomicBoolean closed = new AtomicBoolean();
/** Reference to the JVM shutdown hook, if registered. */
private Thread shutdownHook;
/** ResourcePatternResolver used by this context. */
private ResourcePatternResolver resourcePatternResolver;
/** LifecycleProcessor for managing the lifecycle of beans within this context. */
private LifecycleProcessor lifecycleProcessor;
// 用于事件发布的类
private ApplicationEventMulticaster applicationEventMulticaster;
// 对启动事件进行监控的类
private ApplicationStartup applicationStartup = ApplicationStartup.DEFAULT;
// 监听Spring事件的监听器
private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
/** Local listeners registered before refresh. */
@Nullable
private Set<ApplicationListener<?>> earlyApplicationListeners;
/** ApplicationEvents published before the multicaster setup. */
@Nullable
private Set<ApplicationEvent> earlyApplicationEvents;
protected ConfigurableEnvironment createEnvironment() {
return new StandardEnvironment();
}
// 发送Spring事件
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
ApplicationEvent applicationEvent;
if (event instanceof ApplicationEvent) {
applicationEvent = (ApplicationEvent) event;
}
else {
// 如果事件类型不是ApplicationEvent,则使用PayloadApplicationEvent进行发送
applicationEvent = new PayloadApplicationEvent<>(this, event);
if (eventType == null) {
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 {
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}
// Publish event via parent context as well...
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext) {
((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
}
else {
this.parent.publishEvent(event);
}
}
}
public void setParent(@Nullable ApplicationContext parent) {
this.parent = parent;
if (parent != null) {
Environment parentEnvironment = parent.getEnvironment();
if (parentEnvironment instanceof ConfigurableEnvironment) {
getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);
}
}
}
// 核心方法,刷新IOC容器,进行IOC容器的初始化,新建ApplicationContext的构造方法中,会调用refresh()
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
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();
}
}
}
/**
* Prepare this context for refreshing, setting its startup date and
* active flag as well as performing any initialization of property sources.
*/
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());
}
}
// Initialize any placeholder property sources in the context environment.
initPropertySources();
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
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<>();
}
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
if (!shouldIgnoreSpel) {
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
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.ignoreDependencyInterface(ApplicationStartupAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
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));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (!NativeDetector.inNativeImage() && 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()));
}
// Register default environment beans.
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());
}
}
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null &&
beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
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() + "]");
}
}
}
protected void initLifecycleProcessor() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
this.lifecycleProcessor =
beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
if (logger.isTraceEnabled()) {
logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
}
}
else {
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
this.lifecycleProcessor = defaultProcessor;
beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
if (logger.isTraceEnabled()) {
logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
}
}
}
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!
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);
}
}
}
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no BeanFactoryPostProcessor
// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
@SuppressWarnings("deprecation")
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// Initialize lifecycle processor for this context.
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
if (!NativeDetector.inNativeImage()) {
LiveBeansView.registerApplicationContext(this);
}
}
protected void cancelRefresh(BeansException ex) {
this.active.set(false);
}
// 设置JVM钩子函数,应用于IOC容器关闭监听
public void registerShutdownHook() {
if (this.shutdownHook == null) {
// No shutdown hook registered yet.
this.shutdownHook = new Thread(SHUTDOWN_HOOK_THREAD_NAME) {
@Override
public void run() {
synchronized (startupShutdownMonitor) {
doClose();
}
}
};
Runtime.getRuntime().addShutdownHook(this.shutdownHook);
}
}
public void close() {
synchronized (this.startupShutdownMonitor) {
doClose();
// If we registered a JVM shutdown hook, we don't need it anymore now:
// We've already explicitly closed the context.
if (this.shutdownHook != null) {
try {
Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
}
catch (IllegalStateException ex) {
// ignore - VM is already shutting down
}
}
}
}
@SuppressWarnings("deprecation")
protected void doClose() {
// Check whether an actual close attempt is necessary...
if (this.active.get() && this.closed.compareAndSet(false, true)) {
if (logger.isDebugEnabled()) {
logger.debug("Closing " + this);
}
if (!NativeDetector.inNativeImage()) {
LiveBeansView.unregisterApplicationContext(this);
}
try {
// Publish shutdown event.
publishEvent(new ContextClosedEvent(this));
}
catch (Throwable ex) {
logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
}
// Stop all Lifecycle beans, to avoid delays during individual destruction.
if (this.lifecycleProcessor != null) {
try {
this.lifecycleProcessor.onClose();
}
catch (Throwable ex) {
logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
}
}
// Destroy all cached singletons in the context's BeanFactory.
destroyBeans();
// Close the state of this context itself.
closeBeanFactory();
// Let subclasses do some final clean-up if they wish...
onClose();
// Reset local application listeners to pre-refresh state.
if (this.earlyApplicationListeners != null) {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Switch to inactive.
this.active.set(false);
}
}
protected void destroyBeans() {
getBeanFactory().destroySingletons();
}
@Override
public void start() {
getLifecycleProcessor().start();
publishEvent(new ContextStartedEvent(this));
}
@Override
public void stop() {
getLifecycleProcessor().stop();
publishEvent(new ContextStoppedEvent(this));
}
@Override
public boolean isRunning() {
return (this.lifecycleProcessor != null && this.lifecycleProcessor.isRunning());
}
//---------------------------------------------------------------------
// Abstract methods that must be implemented by subclasses
//---------------------------------------------------------------------
// 子类必须实现以进行实际的配置加载
protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;
//Subclasses must implement this method to release their internal bean factory.
protected abstract void closeBeanFactory();
// Subclasses must return their internal bean factory here. They should implement the lookup efficiently, so that it can be called repeatedly without a performance penalty.
public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
}
1.2.3 ApplicationContextEvent事件
org.springframework.context.event.ApplicationContextEvent是ApplicationEvent的实现虚类,实现如下:
public abstract class ApplicationContextEvent extends ApplicationEvent {
// Create a new ContextStartedEvent.
public ApplicationContextEvent(ApplicationContext source) {
super(source);
}
// Get the {@code ApplicationContext} that the event was raised for.
public final ApplicationContext getApplicationContext() {
return (ApplicationContext) getSource();
}
}
ApplicationContextEvent的实现类如下: ContextClosedEvent (org.springframework.context.event):IOC关闭事件 ContextRefreshedEvent (org.springframework.context.event):IOC刷新事件 ContextStoppedEvent (org.springframework.context.event):IOC停止事件
ContextStartedEvent (org.springframework.context.event):IOC启动事件
1.2.4 PathMatchingResourcePatternResolver
AbstractApplicationContext使用的ResourcePatternResolver实现为PathMatchingResourcePatternResolver,org.springframework.core.io.support.PathMatchingResourcePatternResolver实现了根据正则表达式匹配配置文件:
1.2.5 LifecycleProcessor
org.springframework.context.LifecycleProcessor实现Lifecycle接口,可以接受refresh和close事件,实现如下:
public interface LifecycleProcessor extends Lifecycle {
// Notification of context refresh, e.g. for auto-starting components.
void onRefresh();
// Notification of context close phase, e.g. for auto-stopping components.
void onClose();
}
org.springframework.context.support.DefaultLifecycleProcessor为LifecycleProcessor的默认实现类,
public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactoryAware {
// Start all registered beans that implement {@link Lifecycle} and are not already running
@Override
public void start() {
startBeans(false);
this.running = true;
}
// Stop all registered beans that implement {@link Lifecycle} and are currently running.
@Override
public void stop() {
stopBeans();
this.running = false;
}
@Override
public void onRefresh() {
startBeans(true);
this.running = true;
}
@Override
public void onClose() {
stopBeans();
this.running = false;
}
@Override
public boolean isRunning() {
return this.running;
}
private void startBeans(boolean autoStartupOnly) {
// 获取Lifecycle的实现类
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
// 封装为LifecycleGroup,按照phase进行分组,phase相同的bean,一起进行启停
Map<Integer, LifecycleGroup> phases = new TreeMap<>();
lifecycleBeans.forEach((beanName, bean) -> {
if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
int phase = getPhase(bean);
phases.computeIfAbsent(
phase,
p -> new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly)
).add(beanName, bean);
}
});
if (!phases.isEmpty()) {
phases.values().forEach(LifecycleGroup::start);
}
}
/ Start the specified bean as part of the given set of Lifecycle beans, making sure that any beans that it depends on are started first.
private void doStart(Map<String, ? extends Lifecycle> lifecycleBeans, String beanName, boolean autoStartupOnly) {
Lifecycle bean = lifecycleBeans.remove(beanName);
if (bean != null && bean != this) {
String[] dependenciesForBean = getBeanFactory().getDependenciesForBean(beanName);
for (String dependency : dependenciesForBean) {
doStart(lifecycleBeans, dependency, autoStartupOnly);
}
if (!bean.isRunning() &&
(!autoStartupOnly || !(bean instanceof SmartLifecycle) || ((SmartLifecycle) bean).isAutoStartup())) {
try {
bean.start();
}
catch (Throwable ex) {
throw new ApplicationContextException("Failed to start bean '" + beanName + "'", ex);
}
}
}
}
private void stopBeans() {
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
Map<Integer, LifecycleGroup> phases = new HashMap<>();
lifecycleBeans.forEach((beanName, bean) -> {
int shutdownPhase = getPhase(bean);
LifecycleGroup group = phases.get(shutdownPhase);
if (group == null) {
group = new LifecycleGroup(shutdownPhase, this.timeoutPerShutdownPhase, lifecycleBeans, false);
phases.put(shutdownPhase, group);
}
group.add(beanName, bean);
});
if (!phases.isEmpty()) {
List<Integer> keys = new ArrayList<>(phases.keySet());
keys.sort(Collections.reverseOrder());
for (Integer key : keys) {
phases.get(key).stop();
}
}
}
// Stop the specified bean as part of the given set of Lifecycle beans, making sure that any beans that depends on it are stopped first.
private void doStop(Map<String, ? extends Lifecycle> lifecycleBeans, final String beanName,
final CountDownLatch latch, final Set<String> countDownBeanNames) {
Lifecycle bean = lifecycleBeans.remove(beanName);
if (bean != null) {
String[] dependentBeans = getBeanFactory().getDependentBeans(beanName);
for (String dependentBean : dependentBeans) {
doStop(lifecycleBeans, dependentBean, latch, countDownBeanNames);
}
try {
if (bean.isRunning()) {
if (bean instanceof SmartLifecycle) {
countDownBeanNames.add(beanName);
((SmartLifecycle) bean).stop(() -> {
latch.countDown();
countDownBeanNames.remove(beanName);
});
}
else {
bean.stop();
}
}
else if (bean instanceof SmartLifecycle) {
// Don't wait for beans that aren't running...
latch.countDown();
}
}
catch (Throwable ex) {
}
}
}
// overridable hooks
// Retrieve all applicable Lifecycle beans: all singletons that have already been created, as well as all SmartLifecycle beans (even if they are marked as lazy-init).
protected Map<String, Lifecycle> getLifecycleBeans() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
Map<String, Lifecycle> beans = new LinkedHashMap<>();
String[] beanNames = beanFactory.getBeanNamesForType(Lifecycle.class, false, false);
for (String beanName : beanNames) {
String beanNameToRegister = BeanFactoryUtils.transformedBeanName(beanName);
boolean isFactoryBean = beanFactory.isFactoryBean(beanNameToRegister);
String beanNameToCheck = (isFactoryBean ? BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName);
if ((beanFactory.containsSingleton(beanNameToRegister) &&
(!isFactoryBean || matchesBeanType(Lifecycle.class, beanNameToCheck, beanFactory))) ||
matchesBeanType(SmartLifecycle.class, beanNameToCheck, beanFactory)) {
Object bean = beanFactory.getBean(beanNameToCheck);
if (bean != this && bean instanceof Lifecycle) {
beans.put(beanNameToRegister, (Lifecycle) bean);
}
}
}
return beans;
}
private boolean matchesBeanType(Class<?> targetType, String beanName, BeanFactory beanFactory) {
Class<?> beanType = beanFactory.getType(beanName);
return (beanType != null && targetType.isAssignableFrom(beanType));
}
protected int getPhase(Lifecycle bean) {
return (bean instanceof Phased ? ((Phased) bean).getPhase() : 0);
}
}
1.2.6 ApplicationStartup
org.springframework.core.metrics.ApplicationStartup的实现接口,可以接收启动过程中的启动信息。
1.2.7 ConfigurableEnvironment
org.springframework.core.env.ConfigurableEnvironment接口是Spring配置管理接口,实现如下:
public interface ConfigurableEnvironment extends Environment, ConfigurablePropertyResolver {
// Specify the set of profiles active for this {@code Environment}. Profiles are evaluated during container bootstrap to determine whether bean definitions should be registered with the container.
void setActiveProfiles(String... profiles);
void addActiveProfile(String profile);
// Specify the set of profiles to be made active by default if no other profiles are explicitly made active through {@link #setActiveProfiles}.
void setDefaultProfiles(String... profiles);
MutablePropertySources getPropertySources();
// 获取系统配置属性,比如JVM的配置
Map<String, Object> getSystemProperties();
// 获取系统环境配置,WIN10的环境变量可以通过这种方式获取
Map<String, Object> getSystemEnvironment();
// Append the given parent environment's active profiles, default profiles and property sources to this (child) environment's respective collections of each.
void merge(ConfigurableEnvironment parent);
}
org.springframework.core.env.PropertyResolver的接口实现如下:
public interface PropertyResolver {
// 判断是否包含对应的key的配置
boolean containsProperty(String key);
String getProperty(String key);
String getProperty(String key, String defaultValue);
<T> T getProperty(String key, Class<T> targetType);
<T> T getProperty(String key, Class<T> targetType, T defaultValue);
String getRequiredProperty(String key) throws IllegalStateException;
// 将value转换为对应的类型
<T> T getRequiredProperty(String key, Class<T> targetType) throws IllegalStateException;
// Resolve ${...} placeholders in the given text, replacing them with corresponding property values as resolved by {@link #getProperty}. Unresolvable placeholders with no default value are ignored and passed through unchanged.
String resolvePlaceholders(String text);
// Unresolvable placeholders with no default value will cause an IllegalArgumentException to be thrown.
String resolveRequiredPlaceholders(String text) throws IllegalArgumentException;
}
org.springframework.core.env.ConfigurablePropertyResolver继承PropertyResolver接口,扩展配置可进行设置的能力,实现如下:
public interface ConfigurablePropertyResolver extends PropertyResolver {
// 类型转换实现类
ConfigurableConversionService getConversionService();
// 设置转换实现类
void setConversionService(ConfigurableConversionService conversionService);
// Set the prefix that placeholders replaced by this resolver must begin with.
void setPlaceholderPrefix(String placeholderPrefix);
// Set the suffix that placeholders replaced by this resolver must end with.
void setPlaceholderSuffix(String placeholderSuffix);
// Specify the separating character between the placeholders replaced by this resolver and their associated default value, or {@code null} if no such special character should be processed as a value separator.
void setValueSeparator(@Nullable String valueSeparator);
// Set whether to throw an exception when encountering an unresolvable placeholder nested within the value of a given property.
void setIgnoreUnresolvableNestedPlaceholders(boolean ignoreUnresolvableNestedPlaceholders);
// Specify which properties must be present, to be verified by {@link #validateRequiredProperties()}.
void setRequiredProperties(String... requiredProperties);
// Validate that each of the properties specified by {@link #setRequiredProperties} is present and resolves to a non-{@code null} value.
void validateRequiredProperties() throws MissingRequiredPropertiesException;
}