文章目录
为之前的内容进行拓展,首先,添加initMethod和destroy方法. 具体执行时 destroy 通过注册钩子来实现,initMethod通过在之前编排的创建bean时加入增强的方法。
初始化
BeanDefinition
为BeanDefinition添加 属性 initMethodName | destroyMethodName
分别为初始化方法名以及销毁方法名
XmlBeanDefinitionReader 读取配置的方法
String initMethod = bean.getAttribute("init-method");
String destroyMethodName = bean.getAttribute("destroy-method");
//额外设置到beanDefinition中
beanDefinition.setInitMethodName(initMethod);
beanDefinition.setDestroyMethodName(destroyMethodName);
AbstractAutowireCapableBeanFactory (创建bean)
在applyBeanPostProcessorsBeforeInitialization之后执行
public Object initializeBean(String beanName, Object bean, BeanDefinition beanDefinition){
// 1. 执行 BeanPostProcessor Before 处理
Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
// 执行 Bean 对象的初始化方法
try {
invokeInitMethods(beanName, wrappedBean, beanDefinition);
} catch (Exception e) {
throw new BeansException("Invocation of init method of bean[" + beanName + "] failed", e);
}
// 2. 执行 BeanPostProcessor After 处理
wrappedBean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
return wrappedBean;
}
invokeInitMethods
private void invokeInitMethods(String beanName, Object bean, BeanDefinition beanDefinition) throws Exception {
// 1. 实现接口 InitializingBean 调用方法.
if (bean instanceof InitializingBean) {
((InitializingBean) bean).afterPropertiesSet();
}
// 2. 配置信息 init-method {判断是为了避免二次执行销毁}
String initMethodName = beanDefinition.getInitMethodName();
if(StrUtil.isNotEmpty(initMethodName)){
Method initMethod = beanDefinition.getBeanClass().getMethod(initMethodName);
if(null == initMethod){
throw new BeansException("Could not find an init method named '" + initMethodName + "' on bean with name '" + beanName + "'");
}
initMethod.invoke(bean);
}
}
销毁
当context容器执行close方法时调用bean销毁的方法。
注册shutdownHook钩子函数销毁时执行close方法.
@Override
public void registerShutdownHook() {
Runtime.getRuntime().addShutdownHook(new Thread(this::close));
}
@Override
public void close() {
getBeanFactory().destroySingletons();
}
被销毁的bean是什么时候被存入 disposableBeans 中的呢
DefaultSingletonBeanRegistry
提供了注册和销毁的方法。
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {
private Map<String, Object> singletonObjects = new HashMap<>();
private final Map<String, DisposableBean> disposableBeans = new HashMap<>();
@Override
public Object getSingleton(String beanName) {
return singletonObjects.get(beanName);
}
protected void addSingleton(String beanName, Object singletonObject) {
singletonObjects.put(beanName, singletonObject);
}
public void registerDisposableBean(String beanName, DisposableBean bean) {
disposableBeans.put(beanName, bean);
}
public void destroySingletons() {
Set<String> keySet = this.disposableBeans.keySet();
Object[] disposableBeanNames = keySet.toArray();
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
Object beanName = disposableBeanNames[i];
DisposableBean disposableBean = disposableBeans.remove(beanName);
try {
disposableBean.destroy();
} catch (Exception e) {
throw new BeansException("Destroy method on bean with name '" + beanName + "' threw an exception", e);
}
}
}
}
当我们使用到某个bean时会触发它的createBean方法。 当然默认的单例bean会提前自动创建.
@Override
protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException {
Object bean = null;
try {
bean = createBeanInstance(beanDefinition, beanName, args);
// 给 Bean 填充属性
applyPropertyValues(beanName, bean, beanDefinition);
// 执行bean的初始化方法和BeanPostProcessor的前置和后置处理方法
bean = initializeBean(beanName,bean,beanDefinition);
} catch (Exception e) {
throw new BeansException("Instantiation of bean failed", e);
}
// 注册实现了 DisposableBean 接口的 Bean 对象
registryDisposableBeanIfNecessary(beanName,bean,beanDefinition);
addSingleton(beanName, bean);
return bean;
}
// 注册DisposableBean
protected void registryDisposableBeanIfNecessary(String beanName, Object bean, BeanDefinition beanDefinition){
if (bean instanceof DisposableBean || StrUtil.isNotEmpty(beanDefinition.getDestroyMethodName())) {
registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, beanDefinition));
}
}
createBean到目前为止的流程:
- createBeanInstance 创建实例对象
- applyPropertyValues 注入对象
- initializeBean 初始化bean 又分为
) 3.1 执行beforePostProcessor
) 3.2 执行init-method方法
) 3.3 执行afterPostProcessor
refresh方法:
- 创建bean工厂加载全部的beanDefinition从xml中.;
- 执行beanFactoryPostProcessors 工厂方法的增强;
- 注册registerBeanPostProcessors 注册bean后处理器也就是把beanPostProcessor添加到List中
- 提前实例化单例对象 接上面的流程。