从源码分析Spring的生命周期
Posted 赵晓东-Nastu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从源码分析Spring的生命周期相关的知识,希望对你有一定的参考价值。
一、目录结构
(1)MyBeanFactoryPostProcessor
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanFactoryPostProcessor的--->"+"postProcessBeanFactory");
}
}
(2)MyInstantiationAwareBeanPostProcessorAdapter
@Component
public class MyInstantiationAwareBeanPostProcessorAdapter implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("MyInstantiationAwareBeanPostProcessorAdapter--->"+"postProcessBeforeInstantiation");
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println("MyInstantiationAwareBeanPostProcessorAdapter--->"+"postProcessAfterInstantiation");
return false;
}
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
System.out.println("MyInstantiationAwareBeanPostProcessorAdapter--->"+"postProcessPropertyValues");
return null;
}
}
(3)MyBeanPostProcessor
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("MyBeanPostProcessor---->"+"postProcessBeforeInitialization");
return null;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("MyBeanPostProcessor---->"+"postProcessAfterInitialization");
return null;
}
}
(4)user
package com.iocbean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class User implements ApplicationContextAware, BeanFactoryAware , BeanNameAware, InitializingBean, DisposableBean {
@Value("1")
private int id;
@Value("zxd")
private String name;
private ApplicationContext applicationContext;
private BeanFactory beanFactory;
public User() {
System.out.println("[构造器]---》实例化User");
}
public BeanFactory getBeanFactory() {
return beanFactory;
}
public int getId() {
return id;
}
public void setId(int id) {
System.out.println("属性注入id");
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("[注入属性]注入属性name");
this.name = name;
}
public ApplicationContext getApplicationContext() {
return applicationContext;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("[BeanFactoryAware]调用BeanFactoryAware.setBeanFactory()");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("[ApplicationContextAware接口]调用ApplicationContextAware.setApplicationContext");
}
@Override
public void setBeanName(String name) {
System.out.println("【BeanNameAware接口】调用BeanNameAware.setBeanName()");
}
@Override
public void destroy() throws Exception {
System.out.println("[DiposibleBean接口]调用DiposibleBean.destory()");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("【InitializingBean接口】调用InitializingBean.afterPropertiesSet()");
}
}
(5)Test
package com.iocbean;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class TestIOC {
public static void main(String[] args) {
System.out.println("现在开始初始化容器");
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);
System.out.println("初始化成功");
User bean = ac.getBean(User.class);
System.out.println(bean.getId());
System.out.println(bean);
}
}
二、流程图
三、说明
首先一共有两种方式可以定义Bean,一种是通过xml的方式,另一种是通过注解的方式,加载配置文件来启动ApplicationContext,
执行ClassPathXmlApplicationContext的构造器函数,走到refresh()方法
// Prepare this context for refreshing.
//准备工作,记录下容器的启动时间、标记"已启动“状态处理配置文件中的占位符
prepareRefresh();
//这步比较关键,这步完成后,配置文件就会解析成一个个Bean定义,注册到BeanFactory中,
//当然,这里说的Bean还没有初始化,只是配置信息都提取出来了。
//注册也只是将这些信息都保存到了注册中心(说到底核心是一个beanName->beanDefinition的map)
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// Configure the bean definition reader with this context's
// resource loading environment.
beanDefinitionReader.setEnvironment(getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// Allow a subclass to provide custom initialization of the reader,
// then proceed with actually loading the bean definitions.
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
通过beanDefinitionReader来读取。
然后到BeanDefinition,通过Spring容器来存储bean,首先进行实例化
finishBeanFactoryInitialization
然后我们进去这个方法里面,走到最后面发现,有一个实例化剩下的非懒加载的单例对象
//实例化剩下的所有的非懒加载的单例对象
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
//如果beanName对应的bean不是FactoryBean,只是普通的bean,通过beanName获取bean实例
getBean(beanName);
@Override
public Object getBean(String name) throws BeansException {
//此方法是实际获取bean的方法,也是触发依赖注入的方法
return 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 {
final String beanName = transformedBeanName(name);
Object bean;
// 接下来就是获取bean的对象
// 尝试通过bean名称获取目标bean对象,比如这里的A对象
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
Object singletonInstance = getSingleton(beanName);
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//尝试从缓存中获取成品的目标对象,如果存在,则直接返回
Object singletonObject = this.singletonObjects.get(beanName);
//如果缓存中不存在目标对象,则判断当前对象是否已经处于创建过程中,
//第一次尝试获取A对象的实例之后,就会将A对象标记为正在创建中,因而最后再尝试获取A对象的时候这里的if就会为true
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
//这里的singletonFactories是一个map ,其key是bean的名称,而值是一个ObjectFactory类型的
//对象,这里对于A和B而言,调用getObject()方法返回的就是A和B对象的实例,无论是否是半成品
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//获取目标对象的实例
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
从代码中可以看出,先出一级缓存中查询是否有当前的bean对象,如果是第一次的话,没有则返回null。
接下来就是createBean了
//这里的目标对象都是单例的
// Create bean instance.
if (mbd.isSingleton()) {
//这里就尝试创建目标对象。第二个参数传的就是一个ObjectFactory类型的对象,这里是
//使用Java8的lamada表达式写的,只要上面的getSingleton()方法返回值为空,则会调用这里的
//getSingleton方法
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);
}
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
没有就创建实例
//没有就创建实例
if (instanceWrapper == null) {
//根据执行bean使用对应的策略创建新的实例,如:工厂方法,构造函数主动注入,简单初始化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//如果支持,这里就会将当前生产的半成品的bean放到singletonFactories中,
//这个singletonFactories 就是前面第一个getSingleton()方法中所使用的singletonFactories属性,也就是说
//这里就是封装半成品的bean的地方,而这里的getEarlyBeanReference()本质上
//是直接将放入的第三个参数,也就是目标bean直接返回
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
//在初始化实例之后,这里就是判断当前bean是否依赖了其他的bean,如果依赖了
//就会递归的调用getBean()方法尝试获取目标bean
populateBean(beanName, mbd, instanceWrapper);
initializeBean(beanName, exposedObject, mbd);
//BeanNameAware,BeanFactoryAware, ApplicationContextAware
invokeAwareMethods(beanName, bean);
applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
InitializingBean的afterPropertiesSet<init-method>
InitializingBean的afterPropertiesSet<init-method>
applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
这就是初始化完成
四、applicationContext和beanFactory
BeanFactory在启动的时候不会去实例化Bean,中有从容器中拿Bean的时候才会去实例化;
ApplicationContext在启动的时候就把所有的Bean全部实例化了。它还可以为Bean配置lazy-init=true来让Bean延迟实例化;
五、总结
以上是关于从源码分析Spring的生命周期的主要内容,如果未能解决你的问题,请参考以下文章