下图是spring启动过程中加载一个类到 IOC 容器的整个流程:
1.加载流程描述
开发人员一般通过xml文件中定义 bean 标签或者加spring的相关注解(如 @Component、@Service、@Controller、@Configuration 等相关注解)让 spring 启动的时候识别需要加载的类,通过 Bean 的阅读器(BeanDefinitionReader )加载 bean 并解析为 BeanDefinition ,然后调用一系列的 BeanFactoryPostProcessor 对 Bean 对应的 BeanDefinition 对象进行二次改造最终存储到 BeanDefinition 容器中。
所有的需要实例化的类的 BeanDefinition 对象存放到 BeanDefinition 容器之后,spring 从 BeanDefinition 容器中获取 Bean 的 BeanDefinition 对象实例化 bean,这个时候的实例化 Bean 并不是完整的 Bean 对象,需要经历过填充属性、调用一系列 Aware 接口完成对 Bean 的改在、调用 Bean 的前置处理器、用户定义的 init-method 方法、Bean的后置处理器,最终生成完整的 Bean 实例存放到 Bean 的单例容器中等待系统对Bean的调用。
当系统卸载时,会对所有实例化的Bean进行销毁,此时Bean的整个声明周期结束。
2.源码加载流程跟踪
以下代码完全按照代码运行的先后顺序贴出来:
1.1 入口代码
public class AnoTationTest {
public static void main(String[] args) {
//初始化容器,加载配置文件
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(AppConfig.class);
//获取bean
JllBean jllBean = (JllBean)app.getBean("jllBean");
System.out.println(jllBean);
}
}
1.2 进入AnnotationConfigApplicationContext父构造器,创建IOC容器。
public GenericApplicationContext() {
//创建IOC容器
this.beanFactory = new DefaultListableBeanFactory();
}
1.3 进入AnnotationConfigApplicationContext构造器。
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//主要作用:创建BeanDefinitionReader并加载spring内部类为BeanDefinition。
this();
//加载用户加注解的类为BeanDefinition
register(annotatedClasses);
refresh();
}
1.4 进入2.3代码中的register()的代码中
public void register(Class<?>... annotatedClasses) {
Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
//annotatedClasses为用户定义的注解class,reader会把这些class加载进BeanDefinitionMap中
this.reader.register(annotatedClasses); //---> 1
}
//为上述代码 1 的调用
public void register(Class<?>... annotatedClasses) {
for (Class<?> annotatedClass : annotatedClasses) {
registerBean(annotatedClass);//---> 2
}
}
//为上述代码 2 的调用
public void registerBean(Class<?> annotatedClass) {
doRegisterBean(annotatedClass, null, null, null);
}
1.5 进入AnnotatedBeanDefinitionReader的doRegisterBean方法,加载用户注解的类到BeanDefinitionMap
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
//此处省略n行代码
...
...
//加载用户注解的类到BeanDefinitionMap
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
1.6 进入BeanDefinitionReaderUtils的registerBeanDefinition方法,加载用户注解的类到BeanDefinitionMap。
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
//加载用户注解的类到BeanDefinitionMap
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
1.7 进入GenericApplicationContext方法
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
}
1.8 进入DefaultListableBeanFactory的registerBeanDefinition的方法的this.beanDefinitionMap.put(beanName, beanDefinition),至此完成用户定义的注解的类加载进BeanDefinition容器。
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
BeanDefinition oldBeanDefinition;
oldBeanDefinition = this.beanDefinitionMap.get(beanName);
if (oldBeanDefinition != null) {
//此处省略n行代码
...
...
...
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
//把用户定义的注解的类加载进BeanDefinition容器中---------------重要点
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
else {
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (oldBeanDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
以上为第一阶段,代码流程完成了spring框架先创建容器,然后再把加注解的类加载进BeanDefinition容器的验证。
下面看第二阶段流程:获取 BeanDefinition 实例化为 bean 对象。
2.1 执行AbstractApplicationContext的refresh()代码的invokeBeanFactoryPostProcessors(beanFactory)代码,调用一系列的BeanFactoryPostProcessors,主要是用来改造BeanDefinition。
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);
// 调用一系列的BeanFactoyrPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// 此处省略若干行代码
...
...
}
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();
}
}
}
以上代码验证了生成BeanDefinition对象后调用一系列的BeanFactoryProcessor。
2.2 调用registerBeanPostProcessors(beanFactory)代码,注册beanPostProcessor。
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);
// 调用一系列的BeanFactoyrPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//注册BeanPostProcessor,方便后续实例化对象的过程中调用,主要在 beforeBeanPostProcessor 和 afterBeanPostProcessor。
registerBeanPostProcessors(beanFactory);
//此处省略若干行代码
...
}
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();
}
}
}
2.3 调用registerBeanPostProcessors(beanFactory)代码,里面代码为实例化bean的过程
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);
// 注册BeanPostProcessor,方便后续实例化对象的过程中调用,主要在 beforeBeanPostProcessor 和 afterBeanPostProcessor。
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// 此处省略若干行代码
...
// 实例化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();
}
}
}
2.4 跟进2.3代码的finishBeanFactoryInitialization(beanFactory)方法,实例化bean过程。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 此处省略若干行代码
...
// 实例化bean过程
beanFactory.preInstantiateSingletons();
}
2.5 继续跟进2.4中的beanFactory.preInstantiateSingletons()的方法。
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("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()) {
//判断是不是FactoryBean对象--------------------1
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<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {//不是FactoryBean对象是获取BeanMap容器中是否有bean。--------------2
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
2.6 继续跟进2.5中getBean(beanName)的代码。
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
2.7 继续跟进2.6中doGetBean(name, null, null, false)的代码。
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 此处省略若干行代码
...
...
// Create bean instance.
if (mbd.isSingleton()) {
//创建bean--------------------------------------1
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 此处省略若干行代码
...
return (T) bean;
}
2.8 继续跟进2.7代码createBean(beanName, mbd, args)。
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
//此处省略若干行代码
...
...
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
//此处省略若干行代码
...
...
}
2.9 继续跟进2.8的doCreateBean(beanName, mbdToUse, args)代码。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 此处省略了若干行代码
...
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
2.10 继续跟进2.9的代码instantiateBean(beanName, mbd)。
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
//此处省略若干行代码
...
}
else {
//继续实例化------1
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
//此处省略若干行代码
...
return bw;
}
//此处省略若干行代码
...
}
2.11 继续跟进2.10中getInstantiationStrategy().instantiate(mbd, beanName, parent)的代码。
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {
//获取到构造器--------1
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
//实例化--------2
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
2.12 继续跟进2.11中BeanUtils.instantiateClass(constructorToUse)代码。此处判断是否为KotLinType,不是的话通过ctor.newInstance(args)反射的形式创建对象。
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
ReflectionUtils.makeAccessible(ctor);
//此处判断是否为KotLinType,不是的话通过ctor.newInstance(args)反射的形式创建对象。
return (KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
}
catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
}
catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
}
}
2.13 创建完对象后返回到2.10中的代码。此时beanInstance 对象实例化好了,但是这个时候的bean的属性值都是空的。
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
//此时beanInstance 对象实例化好了,但是这个时候的bean的属性值都是空的。
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
以上代码流程验证了:从BeanDefinition获取bean的定义对象创建了一个实例,但是实例中属性值还是为空的。
以下为第三阶段,初始化实例bean的过程:
3.1 继续2.4的debug返回。给instanceWrapper的实例化的对象属性赋值。
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) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//此处省略若干行代码
...
...
try {
//给instanceWrapper的实例化的对象属性赋值,如果通过aware接口赋值的在此处还不能完成赋值。此处能完成类中给属性定义的值。如 private String name = "jll";
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
//此处省略若干行代码
...
...
return exposedObject;
}
以上代码验证了流程图的实例化完对象之后,进行填充属性值的操作。
3.2 继续3.1的代码往下走一步。
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) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//此处省略若干行代码
...
...
try {
//给instanceWrapper的实例化的对象属性赋值,如果通过aware接口赋值的在此处还不能完成赋值。此处能完成类中给属性定义的值。如 private String name = "jll";
populateBean(beanName, mbd, instanceWrapper);
//初始化bean过程,其中调用一系列的aware接口实现的代码
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
//此处省略若干行代码
...
...
return exposedObject;
}
3.3 继续3.2跟进initializeBean(beanName, exposedObject, mbd),看到invokeAwareMethods(beanName, bean)代码,调用一系列的aware接口实现类方法。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//调用一些aware接口实现类的代码,用户也可以自己实现aware接口,完成对bean初始化过程的改造。
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//bean的前置处理器
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//用户用注解注解的initMethod
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//bean的后置处理器。
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
3.4 还是3.3代码的方法,调用bean的前置处理器applyBeanPostProcessorsBeforeInitialization代码;然后调用invokeAwareMethods(beanName, bean)方法,在调用bean的后置处理器applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//调用一些aware接口实现类的代码,用户也可以自己实现aware接口,完成对bean初始化过程的改造。
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//bean的前置处理器
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//用户用注解注解的initMethod
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//bean的后置处理器。
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
至此,return wrappedBean 处的bean为一个完整的bean对象。以上代码流程也验证了流程图:实例化一个对象--->填充属性--->调用一系列aware接口的实现类--->bean的前置处理器--->initMethod初始化方法--->bean的后置处理器--->完整的bean对象。
特别声明:此篇博客为自己学习其它资料后自己重新编写的学习资料,对一些公开课资料有参考的之处,非常感谢其它公开课资料的教育支持。只用于学习记录和分享。