首先我们看其的接口关系,了解其整体结构:
1、我们可以看到,其关于Bean获取的接口接口是HierarchicalBeanFactory(获取父Bean容器)、ListableBeanFactory(可列表的Bean容器-如根据Bean类型、或获取Bean的数量等)
要注意的是、这里与我们前面讲的DefaultListableBeanFactory的区别。我们前面说的DefaultListableBeanFactory,就是一个纯粹的生产Bean的容器,而我们现在讲的ApplicationContext接口其等于是一个管理者,其控制DefaultListableBeanFactory这个生产Bean的将其去生产,并对这个Bean过程生产Bean对象的过程进行进行管控。其实ApplicationContext接口的getBean方法就是再去调用其的成员变量去获取Bean对象的。
2、然后是EnvironmentCapable接口,即决定启动ApplicationContext管理者的环境、如要满足那些条件才能启动、以及要获取哪些Bean、不获取哪些Bean,这个在下面源码中会讲到。
3、然后是ApplicationEventPublisher接口,其主要是进行Event发布,然后对应监视其的Lister进行对应处理。就是一种监视器模式的机制,可以看下这篇文章:https://cloud.tencent.com/developer/article/1449255。
4、ResourcePatternResolver,决定怎样去解析资源,例如怎样确定资源的读取路径。
5、MessageSource,资源的国际化,可以看下这一篇:https://www.cnblogs.com/wade-luffy/p/6073391.html
6、ApplicationContext,接口,这些看其名字,就知道这些方法是干什么的:
7、ConfigurableApplicationContext接口
通过这些方法名我们可以知道,即将前面那些接口要处理的对象通过这个Bean工厂的管理者设置到对应接口的成员变量中。例如添加BeanFactoryPostProcessor、ApplicationListener、ConfigurableEnvironment,这些之后通过源码进行解读。
8、LifeCycle、Closeable,即这个Bean管理者的启动、关闭方法,就是一个容器的生命周期方法,这个在Tomcat容器也是有对应方法。
然后分析其源码:
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 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);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// 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();
}
}
}
首先是:prepareRefresh();
这个主要是初始化ApplicationContext的启动准备,主要是初始化Envirement接口:
// Initialize any placeholder property sources in the context environment
initPropertySources();
// Validate that all properties marked as required are resolvable
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<>();
其中initPropertySources()是将servletContext,servletConfig设置到envirement中:
protected void initPropertySources() {
ConfigurableEnvironment env = getEnvironment();
if (env instanceof ConfigurableWebEnvironment) {
((ConfigurableWebEnvironment) env).initPropertySources(this.servletContext, this.servletConfig);
}
}
而getEnvironment().validateRequiredProperties()是进行启动的参数校验,如果缺少必要的参数,则抛出异常,停止启动。
this.earlyApplicationEvents = new LinkedHashSet<>()由名字就可以知道,提前初始化的ApplicationEvent。具体用处到使用再分析。
第二个是:
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
1、首先是获取前面提到的DefaultListBeanFactory,即Bean工厂。
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
//这个就是从资源中加载BeanDefiniion
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
..............
loadBeanDefinitions(beanDefinitionReader);
}
2、之后是准备这个工厂,直接看prepareBeanFactory()方法的实现:
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
//设置这个工厂的类加载器
beanFactory.setBeanClassLoader(getClassLoader());
//这个是设置SPEL表达式解析器,与主线关系不是很大,就不详细展开
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//而关于PropertyEditorRegistrar,可以看我的这一篇博文:https://blog.csdn.net/qq_25179481/article/details/97620204
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 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 (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());
}
}
然后在这个准备BeanFactory的过程中,添加了一个BeanPostProcessor(关于BeanPostProcessor的源码执行时机可以看我的这篇博文:https://blog.csdn.net/qq_25179481/article/details/89204826)
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
这里分析下ApplicationContextAwareProcessor的源码。
在postProcessBeforeInitialization的的方法中主要是方法invokeAwareInterfaces(bean);
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
这里就与下面的Aware接口对应了。
将这些被忽略的值重新设置上。
第三个是:registerResolvableDependency():
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
这个主要是将这些ApplicationEventPublisher设置到BeanFactory容器中。this也就是指当前这个ApplicationContext,即Spring容器的管理者。要注意Spring容器中的两大类,第一个就是Spring自己的类,这是通过spring自己new出来的,还有一个是交给Sring管理的,就是Bean工厂产生的。归根结底,spring只是在java的基础上对对象做一层封装。它要管理,首先其自己就需要一些对象来形成这个管理者,因为没有谁再去封装spring容器了,而这个对象在java范围内肯定需要new一个对象(当然也可以用反射),所以spring它自己new出这个管理者后(即ApplicationEventPublisher、BeanFactory等),再通过这个管理者去做这个new对象的事,然后spring这个管理者对使用其的人来说,好像是没有new对象一样。
就拿在最前面的environment来说:
public ConfigurableEnvironment getEnvironment() {
if (this.environment == null) {
this.environment = createEnvironment();
}
return this.environment;
}
protected ConfigurableEnvironment createEnvironment() {
return new StandardEnvironment();
}
第三个是:ApplicationListenerDetector,这个直接看源码就知道是什么意思了:
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof ApplicationListener) {
// potentially not detected as a listener by getBeanNamesForType retrieval
Boolean flag = this.singletonNames.get(beanName);
if (Boolean.TRUE.equals(flag)) {
// singleton bean (top-level or inner): register on the fly
this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
}
else if (Boolean.FALSE.equals(flag)) {
if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
// inner bean with other scope - can't reliably process events
logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
"but is not reachable for event multicasting by its containing ApplicationContext " +
"because it does not have singleton scope. Only top-level listener beans are allowed " +
"to be of non-singleton scope.");
}
this.singletonNames.remove(beanName);
}
}
return bean;
}
就是判断这个bean是不是ApplicationListener,如果是,并且已经在单例对象集合中,就将其加到applicationContext的Lister集合中。
4、postProcessBeanFactory(beanFactory)这个是个模板方法,我们看其的其中一个子类:
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}
一个是添加一个PostProcessor接口ServletContextAwareProcessor,这个接口就是给实现了ServletConfigAware
、ServletContextAware接口赋值servletContext与servletConfig,关于servletContext与servletConfig(http://c.biancheng.net/view/3998.html)。
5、invokeBeanFactoryPostProcessors(beanFactory)
这个方法从名字看是执行BeanFactoryPostProcessor接口,但其实里面会执行两个接口方法。一个是BeanFactoryPostProcessor,另一个是BeanDefinitionRegistryPostProcessor,同时这两个接口可以分别通过Order接口来决定执行的顺序。
其中看PostProcessor接口的作用,就是看其要执行的入参是什么,就知道它能干什么了。
BeanFactoryPostProcessor:
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
入参是ConfigurableListableBeanFactory,它就能掉用ConfigurableListableBeanFactory里面的方法去做对应的操作。
BeanDefinitionRegistryPostProcessor:
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
可以看到这个的入参仅仅是BeanDefinitionRegistry,所以其单单使用BeanDefinitionRegistry对应的方法。
6:、registerBeanPostProcessors(beanFactory);
这个通过名字可以知道其是注册BeanPostProcessor到ConfigurableListableBeanFactory,因为这些BeanPostProcessor现在都还是以BeanDefinition的方式存在在ConfigurableListableBeanFactory中,现在就提前出来,将他们放到List中。
同时在分离完后还会注册一个BeanPostProcessor接口的工厂中,ApplicationListenerDetector,这个就是与ApplicationLister相关的,想分离BeanPostProcessor接口一样,也将ApplicaationLister分离出来,以及将Lister移除。
7、initMessageSource();初始化MessageSource,即资源国际化的。
8、initApplicationEventMulticaster(),初始化ApplicationEventMulticaster,用于事件发布的(https://cloud.tencent.com/developer/article/1449255)。
在ApplicationEventMulticaster中运行时间就是这个,就是一ApplicationEvent为参数,调用Lister接口的onApplicationEvent方法
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().getName())) {
// 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.isDebugEnabled()) {
logger.debug("Non-matching event type for listener: " + listener, ex);
}
}
else {
throw ex;
}
}
}
9、onRefresh();就是刷新主题,一般没怎么用,没有收入研究。
10、registerListeners();
这个就是想将BeanPostProcessor、BeanDefinitionRegistryPostProcessor从beanDefinition转化出来一样,将ApplicationLister转化出来添加到ApplicationEventMulticast中。
11、finishBeanFactoryInitialization(beanFactory);结束Bean的初始化。
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 bean post-processor
// (such as a PropertyPlaceholderConfigurer 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();
}
1、首先提取ConversionService接口设置到Bean工厂中。这个好像是跟PropertyEditor接口由于类型转换的,暂时还未具体研究。
2、beanFactory.freezeConfiguration();的作用表示停止BeanDefinition的注册
public void freezeConfiguration() {
this.configurationFrozen = true;
this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
}
public String[] getBeanDefinitionNames() {
String[] frozenNames = this.frozenBeanDefinitionNames;
if (frozenNames != null) {
return frozenNames.clone();
}
else {
return StringUtils.toStringArray(this.beanDefinitionNames);
}
}
3、beanFactory.preInstantiateSingletons();这个就是bean的实例化,将所有bean变成对象的形式。
12、finishRefresh();即结束refresh
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.
LiveBeansView.registerApplicationContext(this);
}
1、其中initLifecycleProcessor,注册LifecycleProcessor接口到bean工厂中,注意这里它是根据名字去获取这个Bean的,所以只会获取到一个LifecycleProcessor。与生命周期相关
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();
}
2、getLifecycleProcessor().onRefresh();就是上面的LifecycleProcessor。然后还有onClose就是用于容器关闭时去进行对应的操作,例如释放一些资源等。
3、publishEvent(new ContextRefreshedEvent(this));发布这个事件。
其内部还是通过获取ApplicationContext的ApplicationContextMulticaster去处理。
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
再下面就是上面提过的。
4、LiveBeansView.registerApplicationContext(this);这个还未研究。
自此,容器的初始化启动各种就完成了。
拿一个初学spring最常见的类ClassPathXmlApplicationContext,看其创建对象的构造方法,就知道到底在什么时候调用refresh初始化ApplicationContext了。
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
完结