mini-spring(简易版spring学习记录)(2)bean的生命周期

58 阅读3分钟

image.png 关于spring里bean的生命流程
如果没有applicationContext,仅使用beanFactory,当我们通过xml扫描文件或是直接注册beanDefinition的时候,我们仅仅只是在DefaultListableBeanFactory 里的beanDefinitionMap里加入了改beanDefinition,而当我们在进行getBean方法之后,beanDefinition才开始真正加载

public Object getBean(String name) throws BeansException {  
Object sharedInstance=getSingleton(name);  
if(sharedInstance!=null){  
return getObjectForBeanInstance(sharedInstance,name);  
}  
BeanDefinition beanDefinition=getBeanDefinition(name);  
Object bean=createBean(name,beanDefinition);  
return getObjectForBeanInstance(bean,name);  
}

我们可以看到 在getBean之后,我们首先会尝试从singleton的三级缓存里获取bean,如果获取不到,才开始从beanDefinition中加载beanDefinition,并尝试创造bean

private Object doCreateBean(String beanName, BeanDefinition beanDefinition) {  
Object bean;  
 
bean=createBeanInstance(beanDefinition);  
if(beanDefinition.isSingleton()){  
Object finalBean=bean;  
addSingletonFactory(beanName, new ObjectFactory<Object>() {  
@Override  
public Object getObject() throws BeansException {  
return getEarlyBeanReference(beanName,beanDefinition,finalBean);  
}  
});  
}  
 
//-----------------------------------------  
//为bean填充属性  
applyPropertyValues(beanName,bean,beanDefinition);  
 
//执行bean的初始化方法和BeanPostProcessor的前置和后置处理方法  
bean = initializeBean(beanName,bean,beanDefinition);  
 
 
registerDisposableBeanIfNecessary(beanName,bean,beanDefinition);  
 
 
Object exposedObject= bean;  
return exposedObject;  
 
}  
 
private void registerDisposableBeanIfNecessary(String beanName, Object bean, BeanDefinition beanDefinition) {  
if(beanDefinition.isSingleton()){  
if(bean instanceof DisposableBean ||StrUtil.isNotEmpty(beanDefinition.getDestroyMethodName())){  
registerDisposableBean(beanName,new DispoeableBeanAdapter(bean,beanName,beanDefinition.getDestroyMethodName()));  
}  
}  
}  
 
private Object initializeBean(String beanName, Object bean, BeanDefinition beanDefinition) {  
if (bean instanceof BeanFactoryAware) {  
((BeanFactoryAware) bean).setBeanFactory(this);  
}  
Object wrappedBean =applyBeanPostProcessorsBeforeInitialization(bean,beanName);  
 
try {  
invokeInitMethods(beanName,wrappedBean,beanDefinition);  
}catch (Throwable t){  
throw new BeansException("Invocation of init method of bean[" + beanName + "] failed", t);  
}  
 
wrappedBean=applyBeanPostProcessorsAfterInitialization(bean,beanName);  
return wrappedBean;  
}  
 
private void invokeInitMethods(String beanName, Object wrappedBean, BeanDefinition beanDefinition) throws Throwable{  
if(wrappedBean instanceof InitializingBean){  
((InitializingBean)wrappedBean).afterPropertiesSet();  
}  
String initMethodName = beanDefinition.getInitMethodName();  
if(StrUtil.isNotEmpty(initMethodName)){  
 
Method initMethod= ClassUtil.getPublicMethod(beanDefinition.getBeanClass(),initMethodName);  
if (initMethod == null) {  
throw new BeansException("Could not find an init method named '" + initMethodName + "' on bean with name '" + beanName + "'");  
}  
initMethod.invoke(wrappedBean);  
}  
}

这段代码有点长,从这里开始,spring也就开始了创造bean的过程,首先是通过某种方法(反射,jdk,cglib)获得类,然后开始用applyPropertyValues尝试为bean填充属性,这里是通过获得PropertyValue之后用反射填充属性的,注意beanFactoryPostProcessor在这里并没有体现,是在Application中实现的。
在填充完bean属性之后也就开始尝试initializeBean,这里首先看一下这个bean是否实现了BeanFactoryAware接口,如果实现了就用模板方法进行调用,然后调用applyBeanPostProcessorsBeforeInitialization,也即beanPostProcessor,通过模板模式的方式来实行postProcessBeforeInitialization方法,(注意这里BeanPostProcessor的登记是在ApplicationContext中进行的),
在before和after之间还有一个invokeInitMethods,这里是执行bean的初始化方法,依旧是模板模式首先看有没有实现InitializingBean接口,然后看beanDefinition中用反射的方式调用设定的初始化方法
在初始化完成之后也就开始registerDisposableBeanIfNecessary(注意这里只有单例bean才会有销毁方法),

private void registerDisposableBeanIfNecessary(String beanName, Object bean, BeanDefinition beanDefinition) {  
if(beanDefinition.isSingleton()){  
if(bean instanceof DisposableBean ||StrUtil.isNotEmpty(beanDefinition.getDestroyMethodName())){  
registerDisposableBean(beanName,new DispoeableBeanAdapter(bean,beanName,beanDefinition.getDestroyMethodName()));   //这里又用了适配器模式 
}  
}  
}

registerDisposableBean将该类放入DefaultSingletonBeanRegister的disposableBeans中,适配器规定了destory方法,在AbstractApplicationContext中

public void registerShutdownHook() {  
Thread shutdownHook = new Thread() {  
public void run() {  
doClose();  
}  
};  
Runtime.getRuntime().addShutdownHook(shutdownHook);  
  
}  
  
protected void doClose() {  
//发布容器关闭事件  
publishEvent(new ContextClosedEvent(this));  
  
//执行单例bean的销毁方法  
destroyBeans();  
}  
  
protected void destroyBeans() {  
getBeanFactory().destroySingletons();  
}

在defaultSingletonBeanfactory中

public void destroySingletons(){  
  
ArrayList<String>beanNames=new ArrayList<>(disposableBeans.keySet());  
for(String beanName:beanNames){  
DisposableBean remove = disposableBeans.remove(beanName);  
try {  
remove.destroy();  
} catch (Exception e) {  
throw new RuntimeException("Destroy method on bean with name '" + beanName + "' threw an exception", e);  
}  
}  
}

在这一切都完成了之后,最后一个方法是为FactoryBean 特设的getEarlyBeanReference()如果发现该类是factoryBean,那么最终返回的是getObject之后的

Object object = beanInstance;  
  
if(object instanceof FactoryBean){  
FactoryBean fb = (FactoryBean) object;  
try {  
if(fb.isSingleton()){  
object = this.factoryBeanObjectCache.get(name);  
if(object==null){  
object=fb.getObject();  
factoryBeanObjectCache.put(name,object);  
}  
}else {  
object=fb.getObject();  
}  
} catch (Exception e) {  
throw new BeansException("FactoryBean threw exception on object[" + name + "] creation", e);  
}  
  
}  
return object;