整体流程
1. new一个ApplicationContext实现类(Spring容器/IOC容器/Spring上下文),比如AnnotationConfigApplicationContext(通过配置类启动)、ClassPathXmlApplicationContext(通过xml配置文件启动)
2. 调用BeanFactory后置处理器完成扫描(invokeBeanFactoryPostProcessors),如ConfigurationClassPostProcessor,解析出类信息
3. 将解析出来的类信息封装成BeanDefinition对象,存储到beanDefinitionMap中
4. 做一些其他的事情,比如国际化,注册BeanPostProcessor等
5. 在finishBeanFactoryInitialization -> preInstantiateSingletons 方法中完成实例化单例bean,循环beanDefinitionMap依次创建,创建前会先判断是否是单例,是否是懒加载,是否抽象类等。然后通过调用BeanFactory.getBean(beanName)方法来创建bean。创建bean的过程分为3大步:a. 实例化(纯净bean);b. 属性注入(@AutoWired、@Value、循环依赖:通过三级缓存解决);c. 初始化(xxxAware、初始化方法回调@PostConstruct)。创建好的单例bean放在DefaultSingletonBeanRegistry类中的Map对象singletonObjects中(又叫做单例池)
实例化过程:通过反射的方式推断构造函数,默认调用无参构造函数实例化;另外也可以通过工厂方法来实例化(指定factory-method和factory-bean,对于@bean注解,factory-method就是@bean修饰的方法,factory-bean就是该方法所在的类),实例化后的bean是一个纯净的bean,各种属性都是null
属性注入:注入@AutoWired和@Value注解修饰的属性,在这期间可能会存在循环依赖的问题,Spring通过三级缓存解决该问题
初始化:在该阶段会调用各种XXXAware扩展接口,然后调用初始化方法,在初始化方法前后会调用postProcessBeforeInitialization和postProcessAfterInitialization方法。
源码
以AnnotationConfigApplicationContext为例
构造方法
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
// 调用无参构造器,
// 在其中实例化了AnnotatedBeanDefinitionReader(在这个过程中会注册一些Spring内部的PostProcessor,比如用来解析配置类的ConfigurationClassPostProcessor)和ClassPathBeanDefinitionScanner
this();
// 将启动类注册到beanDefinitionMap
register(componentClasses);
refresh();
}refresh方法
public void refresh() throws BeansException, IllegalStateException {
this.startupShutdownLock.lock();
try {
this.startupShutdownThread = Thread.currentThread();
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.
// 执行bean工厂后置处理器(比如ConfigurationClassPostProcessor,会解析配置类并根据配置扫描包,将扫描到的bean注册到beanDefinitionMap中,另外还会将配置了进行增强,即创建配置类的动态代理类)
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 注册bean后置处理器
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.
// 实例化所有的单例bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 发布事件ContextRefreshedEvent
finishRefresh();
}
catch (RuntimeException | Error 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 {
contextRefresh.end();
}
}
finally {
this.startupShutdownThread = null;
this.startupShutdownLock.unlock();
}
}finishBeanFactoryInitialization方法
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();
}preInstantiateSingletons方法
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof SmartFactoryBean<?> smartFactoryBean && smartFactoryBean.isEagerInit()) {
getBean(beanName);
}
}
else {
// 通过getBean方法从单例池中循环获取,不存在则创建
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton smartSingleton) {
StartupStep smartInitialize = getApplicationStartup().start("spring.beans.smart-initialize")
.tag("beanName", beanName);
smartSingleton.afterSingletonsInstantiated();
smartInitialize.end();
}
}
}