本文基于SpringBoot5.1.8.RELEASE 版本源码解析
目录
- 0. 代码示例
- 总概要. AbstractApplicationContext.refresh
- 1. obtainFreshBeanFactory(). 创建BeanFactory,加载/注册BeanDefinition
- 2. prepareBeanFactory(). 准备BeanFactory
- 3. postProcessBeanFactory(beanFactory)
- 4. invokeBeanFactoryPostProcessors(beanFactory)执行BeanFactoryPostProcessor(这是一个重要拓展点)
- 5. registerBeanPostProcessors(beanFactory)
- 6. 实例化初始化Bean
我们阅读源码:重点还是要关注其中的拓展点,这样是为了我们更方便的去使用框架的强大功能;其次读懂主要原理,这样给我们带来新的编码思想。对于细枝末节,不必关注太多,除非是碰到问题,或者刚好需要使用这方面功能。
0. 代码示例
-
启动类
public class ExampleStartApplication { public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("classpath:application.xml"); } }
-
application.xml
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire="byName"> <bean id="order" class="com.zeng.entity.Order"/> </beans>
-
启动调试
总概要. AbstractApplicationContext.refresh
- 继承结构图
@Override
public void refresh() throws BeansException, IllegalStateException {
//加锁,防止多次调用refresh(启动或销毁容器等)
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 准备工作,不需要过多关注
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
//创建beanFactory,我们下面分析一下
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.
// 初始化消息资源 MessageSource
initMessageSource();
// Initialize event multicaster for this context.
//初始化应用的事件广播器 ApplicationEventMulticaster
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
//该方法为模板方法,提供给子类扩展实现,可以重写以添加特定于上下文的刷新工作,默认实现为空。
onRefresh();
// Check for listener beans and register them.
//注册监听器ApplicationListener
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//实例化初始化非懒加载的Bean
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();
}
}
}
1. obtainFreshBeanFactory(). 创建BeanFactory,加载/注册BeanDefinition
-
AbstractApplicationContext.obtainFreshBeanFactory()
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); return getBeanFactory(); } //此处refreshBeanFactory调用的是AbstractRefreshableApplicationContext.refreshBeanFactory(我们从继承关系上可以看到这个类) protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;
-
AbstractRefreshableApplicationContext.refreshBeanFactory
protected final void refreshBeanFactory() throws BeansException { //是否已经有BeanFactory,有先销毁 if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { //创建工厂 DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); customizeBeanFactory(beanFactory); //加载BeanDefinition,重点 loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }
-
AbstractXmlApplicationContext.loadBeanDefinitions
@Override protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { //创建XmlBeanDefinitionReader XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); // 省略代码 ... //我们看一下这个 loadBeanDefinitions(beanDefinitionReader); } protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { //获取配置文件 Resource[] configResources = getConfigResources(); if (configResources != null) { reader.loadBeanDefinitions(configResources); } //获取配置文件路径 String[] configLocations = getConfigLocations(); if (configLocations != null) { //加载BeanDefinition reader.loadBeanDefinitions(configLocations); } }
-
AbstractBeanDefinitionReader.loadBeanDefinitions
@Override public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException { Assert.notNull(locations, "Location array must not be null"); int count = 0; for (String location : locations) { count += loadBeanDefinitions(location); } return count; }
-
我们直接看下图,流程比较长,其中的源码不需要过多关注。大致完成的就是xml文件解析,创建BeanDefinition(我们可以看看BeanDefinition接口的源码,主要就是用来描述一个Bean的相关属性,特性,关系等),注册到工厂。我们关注一下红色部分即可。
-
我们看看DefaultListableBeanFactory.registerBeanDefinition。主要是把BeanDefinition放入到beanDefinitionMap。把BeanName放入到beanDefinitionNames,按照Bean的配置的顺序注册Bean。
/** Map of bean definition objects, keyed by bean name. */ private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256); /** List of bean definition names, in registration order. */ private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
2. prepareBeanFactory(). 准备BeanFactory
-
AbstractApplicationContext.prepareBeanFactory()
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // Tell the internal bean factory to use the context's class loader etc. beanFactory.setBeanClassLoader(getClassLoader()); beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // Configure the bean factory with context callbacks. //ApplicationContextAwareProcessor是一个BeanPostProcessor,初始化每个Bean的时候就会调用ApplicationContextAwareProcessor的postProcessBeforeInitialization方法,这里提供了一个重要的拓展点,后面我们会解析调用时机,我们可以看看这个类。 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. // 这个BeanPostProcessor调用时机和上面讲的一样,这个ApplicationListenerDetector是一个注册监听器的功能,如果Bean属于ApplicationListeners,则将其注册到applicationContext中 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. //注册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()); } }
-
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this))
我们看看ApplicationContextAwareProcessor
class ApplicationContextAwareProcessor implements BeanPostProcessor { //省略代码... //初始化bean的时候就会调用postProcessBeforeInitialization方法。我们可以看到这个方法调用了invokeAwareInterfaces(bean),也就是下面那个方法。 @Override @Nullable public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException { AccessControlContext acc = null; //省略代码... if (acc != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareInterfaces(bean); return null; }, acc); } else { invokeAwareInterfaces(bean); } return bean; } //我们可以看到如果Bean实现了以下接口,在初始化的时候就会调用相应的接口方法。 //EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware, ApplicationEventPublisherAware,MessageSourceAware,ApplicationContextAware 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); } } } }
3. postProcessBeanFactory(beanFactory)
允许子类对 BeanFactory 进行后续处理,默认实现为空,留给子类实现。
4. invokeBeanFactoryPostProcessors(beanFactory)执行BeanFactoryPostProcessor(这是一个重要拓展点)
-
AbstractApplicationContext.invokeBeanFactoryPostProcessors
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { //调用BeanFactoryPostProcessor PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // 省略代码 }
-
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors
-
这部分代码不去解析,大家可以看一下,虽然很长,但是主要就是调用BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry和调用BeanFactoryPostProcessor.postProcessBeanFactory。
-
BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor,BeanDefinitionRegistryPostProcessor优先级比BeanFactoryPostProcessor更高。
-
相同的类型优先级:继承PriorityOrdered优先级高于Ordered,高于其他无继承的。同一个Ordered,order值越小,优先级越高。
-
5. registerBeanPostProcessors(beanFactory)
registerBeanPostProcessors代码相对简单,就是注册BeanPostProcessor。我们大致解释一下,不做解析。
- registerBeanPostProcessors主要就是把BeanFactory中BeanDefinition中类型属于BeanPostProcessor的注册到BeanFactory中。此处只做注册,和上面BeanFactoryPostProcessor直接调用不同。
- 优先级:此处优先级和上面一样,也是PriorityOrdered优先级高于Ordered,高于其他无继承的。同一个Ordered,order值越小,优先级越高。
- BeanPostProcessor调用时机是在Bean的初始化前后。
6. 实例化初始化Bean
本篇太长,我们下一篇再介绍。Spring IOC源码解析(2)