Spring的核心功能就是容器功能,用于存放bean的容器。这里有几个概念需要清楚:什么是容器什么又是bean?bean我们可以理解为系统中的类实例对象,而容器在Spring中就是BeanFactory的实现类。
1. 首先定义Spring容器
我们有两种方式配置Spring容器,一种是xml配置方式,一种是java配置方式(一般是结合使用)
// 1. xml配置方式初始化容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("config/beanFactoryTest.xml");
// 2. java配置方式初始化容器
ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
这里容器为什么是ApplicationContext而不是我们上面说的BeanFactory呢,这里需要说明一下ApplicationContext和BeanFactory的区别:
BeanFactory: bean的工厂接口,提供了bean的基本获取方法,BeanFactory的接口关系如下:
ApplicationContext:应用上下文,继承自BeanFactory和其它接口,拥有自己的扩展功能如Environmentcapable和messagesource等(一般使用它)
在前面的示例中我们使用的是ClassPathXmlApplicatinContext和AnnotationConfigApplicationContext在下面的分析中我们以AnnotationConfigApplicationContext为例进行分析说明:
/**
* Create a new AnnotationConfigApplicationContext, deriving bean definitions
* from the given annotated classes and automatically refreshing the context.
* @param annotatedClasses one or more annotated classes,
* e.g. {@link Configuration @Configuration} classes
*/
public AnnotationConfigApplicationContext(Class>... annotatedClasses) {
/* 1. 第一步调用默认构造器创建两个工具对象
* 注解bean定义阅读器
* this.reader = new AnnotatedBeanDefinitionReader(this);
* 类路径bean定义扫描器
* this.scanner = new ClassPathBeanDefinitionScanner(this);
*/
this();
// 2. 注册配置文件
register(annotatedClasses);
// 3. 刷新容器
refresh();
}
第一步为我们创建了阅读器和扫描器,第二步开始注册配置文件,最后一不是最为核心重要的步骤刷新容器。
第一步就不分析了,第二步注册配置文件简单分析一下:这一步其实就是调用了我们第一步创建的阅读器分析配置文件的所有注解信息,然后将注解信息定义对象注册到我们的注册中心(注册中心就是AnnotationConfigApplicationContext)
public void register(Class>... annotatedClasses) {
Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
this.reader.register(annotatedClasses);
}
void doRegisterBean(Class annotatedClass, @Nullable Supplier instanceSupplier, @Nullable String name,
@Nullable Class extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
// 拿到配置文件所有的注解信息
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
.....................
................................
// 将注解配置信息注册到我们的注册中心(ApplicationContext)
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
第三步refresh()也是最核心的一步:在这一步中完成了Spring容器和bean的所有构建工作,具体细分为下面几步
// 1. 预处理---> 刷新前的预处理工作
prepareRefresh();
// 2. 预处理----> 获取bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3. 预处理----> bean工厂使用前预处理
prepareBeanFactory(beanFactory);
// 4. 预处理----->bean工厂后置处理器(留给子类实现)
postProcessBeanFactory(beanFactory);
// 5. 执行后置BeanFactory的后置处理器
invokeBeanFactoryPostProcessors(beanFactory);
// 6. 注册Bean后置处理器
registerBeanPostProcessors(beanFactory);
// 7. 初始化消息组件
initMessageSource();
// 8.初始化应用事件派发器
initApplicationEventMulticaster();
// 9. 初始化其它组件(留给子类扩展)
onRefresh();
// 10.注册监听器
registerListeners();
// 11.实例化所有其它非lazy的bean
finishBeanFactoryInitialization(beanFactory);
// 12.发布容器创建完成事件
finishRefresh();
1. prepareRefresh()
第一步刷新前的准备工作,主要完成容器的环境状态设置
protected void prepareRefresh() {
// 设置启动日期 关闭 活动状态
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
// 初始化属性资源
initPropertySources();
// Validate that all properties marked as required are resolvable
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();
// Allow for the collection of early ApplicationEvents,
//创建早期事件容器
this.earlyApplicationEvents = new LinkedHashSet<>();
}
2. obtainFreshBeanFactory()
在此步骤中我们创建了BeanFactory工厂,跟进源码看一下,通过调用AbstractApplicationContext的 obtainFreshBeanFactory获取工厂,其中refreshBeanFactory()和getBeanFactory()都是接口方法,真实实现在其接口实现类中完成,如上面ApplicationContext接口关系展示,注解配置在GenericApplicationContext中实现,Xml配置在AbstractRefreshableApplicationContext抽象类中实现
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
不管是哪个实现类,最终都是创建了DefaultListableBeanFactory的实例作为容器Bean工厂
/**
* Create a new GenericApplicationContext.
* @see #registerBeanDefinition
* @see #refresh
*/
// 1. 创建工厂实例
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
// 2. 给容器工厂设置序列化ID
@Override
protected final void refreshBeanFactory() throws IllegalStateException {
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
this.beanFactory.setSerializationId(getId());
}
3. prepareBeanFactory()
对刚创建的Bean工厂进行预处理工作,主要就是完成添加bean后置处理器和解析器以及对自动装配接口配置
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 1. 设置类加载器和表达式解析器
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 2.设置bean后置处理器
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); // 3.设置忽略自动装配接口
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.
// 4.注册自动装配组件
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 5.添加bean后置处理器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
................................
}
4. postProcessBeanFactory()
在执行调用BeanFactory的后置处理器之前对后置处理器进行管理(添加、删除....),留给子类扩展功能实现
5. invokeBeanFactoryPostProcessors()
执行BeanFactoryPostProcessor的方法,先将其委托给PostProcessorRegistrationDelegate类来执行:
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 1.委托给PostProcessorRegistrationDelegate类执行
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}
真正调用实现:实现源码较多,就在这里总结一下:
第一步:先执行通过addBeanFactoryPostProcessor方法手动加入容器中的BeanFactoryPostProcessor,判断其类型是否是子类型BeanDefinitionRegistryPostProcessor,如果是子类型先执行子类接口特有的方法,再执行BeanFactoryPostProcessor接口方法:
//1. 对接口先进行优先级排序后执行子接口特有方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//2. 再执行BeanFactoryPostProcessor的接口方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
第二步: 如果我们是通过@Component注解形式将后置处理器放置在容器中的,那么先通过方法拿到所有处理器定义
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
然后通过getBean()实例化处理器
beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)
最后对各个处理器排序后进行方法调用:
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
所以我们可以看到第五步执行BeanFactory的后置处理器是在所有Bean实例化之前就执行了的。
6. initMessageSource()
初始化消息组件,用于国际化、消息绑定、消息解析
// Use empty MessageSource to be able to accept getMessage calls.
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
// 注册单实例消息组件
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
7. initApplicationEventMulticaster()
初始化应用事件广播派发器,用于后续的事件发布工作
// 1. 实例化一个简单的应用广播事件派发器
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
// 2. 将其以单实例的形式注册在BeanFactory中
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
8. onRefresh()
初始化其它特殊组件,留给子类扩展实现
9. registerListeners()
向第七步中的事件派发器中注册监听器
protected void registerListeners() {
// Register statically specified listeners first.
// 1. 向派发器注册已经实例化的监听器
for (ApplicationListener> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// uninitialized to let post-processors apply to them!
// 2.拿到注解形式的监听器并完成实例化注册
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...
// 3.发布早先事件容器中的事件
Set earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
10.finishBeanFactoryInitialization()
这一步是完成其它bean的初始化创建工作,也是容器刷新的核心步骤,下面我们一起来分析它在bean初始化时完成了哪些工作
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
........................
// Instantiate all remaining (non-lazy-init) singletons.
// 初始化单例bean对象
beanFactory.preInstantiateSingletons();
}
继续跟进preInstantiateSingletons进行查看(它是ConfigurableListableBeanFactory的一个接口方法,默认实现是在我们上面创建的默认工厂类DefaultListableBeanFactory)
@Override
public void preInstantiateSingletons() throws BeansException {
List beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
// 1. 创建非懒加载单实例bean
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 2. 判断是否工厂bean
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean> factory = (FactoryBean>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction)
((SmartFactoryBean>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
// 重点: 创建bean
getBean(beanName);
}
}
}
上面一大段代码其实真实创建bean的方法是getBean(beanName)方法,让我们继续跟进,最后进入AbstractBeanFactory的doGetBean()方法,doGetBean()中的代码也很多我们调最重要的来讲:
protected T doGetBean(final String name, @Nullable final Class requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 1.标记此bean已被创建
markBeanAsCreated(beanName);
// 2.拿到bean的所有依赖bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
//如果产生循环依赖则抛出异常
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 注册依赖bean
registerDependentBean(dep, beanName);
try {
//递归创建bean实例
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 3. 判断是否单例bean
if (mbd.isSingleton()){
// 重点 创建bean
return createBean(beanName, mbd, args);
}
// 4. 判断是否原型bean
.........................................................
}
从上面源码我们可以很容器发现bean的实例化是在createBean()中创建的,继续跟入查看,发现踏实AbstarctBeanFactory的接口方法,其实现是在AbstractAutowireCapableBeanFactory中createBean()方法实现的
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {
// 1. 检查bean定义信息
....................................
// 2. 重点:在bean实例化之前给BeanPostProcessor一个执行的机会
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
// 3. bean实例化
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
通过上面源码可知在bean的实例化之前是会又BeanPostProcessor后置处理器的执行机会的,BeanPostProcessor的不同实现的执行时机在整个系统初始化进程中是不同的,首先我们来分析在Bean实例化之前resolveBeforeInstantiation()是来执行哪个bean后置处理的:
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
通过分析源码可知,在Bean初始化之前执行的bean后置处理器是必须要实现InstantiationAwreBeanPostProcessors接口的后置处理器,这个处理器其实就是用来帮助我们实现AOP中生成代理对象的,在后面AOP源码分析中我们再来讲解,这里大家有个概念就可以了,但是读者要清楚这里是调用的InstantiationAwreBeanPostProcessors接口的哪些方法,InstantiationAwreBeanPostProcessors接口继承自BeanPostProcessor接口扩展了四个接口方法:要和它的父类接口的BeforeInstantiation初始化前和初始化后方法分开,在resolve中先调用的是自身实例化前处理器,如果有返回结果调用初始化后处理器。
// 1. Bean实例化之前处理
@Nullable
default Object postProcessBeforeInstantiation(Class> beanClass, String beanName) throws BeansException {
return null;
}
// 2. Bean实例化后处理
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
// 3.工厂使用属性之前处理
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {
return null;
}
// 4. 已废弃不用管
@Deprecated
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
如果resolveBeforeInstantation有返回代理对象那么直接返回代理对象,否则继续调用doCreateBean方法创建bean实例
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)throws BeanCreationException {
// Instantiate the bean
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 通过BeanWrapper进行创建实例并包装bean
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
}
doCreateBean通过调用createBeanInstance创建bean实例并进行BeanWrapper包装,具体如何创建bean继续跟进查看instantiateBean()方法,这里就不继续展开讲解了,bean实例化完成后继续调用populateBean()填充bean属性:
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// 1. 先执行实现了InstantiationAwreBeanPostProcessors接口的实例化后置处理器
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
// 2. 执行成功继续执行属性应用后置处理器
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
// 3. 填充属性
applyPropertyValues(beanName, mbd, bw, pvs);
}
bean的属性填充完后,最后进行调用initializeBean()对bean进行初始化,调用真正初始化方法前先执行aware方法,然后执行Bean初始化前置处理器,初始化后执行后置处理器。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// 1. 执行实现了Aware接口的方法
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction
至此就完成了容器的初始化创建工作finishBeanFactoryInitialization。
11. finishRefresh()
最后一步完成容器刷新工作,在这一步中重要就进行缓存清理,发布事件等工作........
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);
}
最后整个容器初始化流程就做完了。