手写简易版Spring IOC容器04【学习】

为之前的内容进行拓展,首先,添加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到目前为止的流程:

  1. createBeanInstance 创建实例对象
  2. applyPropertyValues 注入对象
  3. initializeBean 初始化bean 又分为
    ) 3.1 执行beforePostProcessor
    ) 3.2 执行init-method方法
    ) 3.3 执行afterPostProcessor

refresh方法:

  1. 创建bean工厂加载全部的beanDefinition从xml中.;
  2. 执行beanFactoryPostProcessors 工厂方法的增强;
  3. 注册registerBeanPostProcessors 注册bean后处理器也就是把beanPostProcessor添加到List中
  4. 提前实例化单例对象 接上面的流程。
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值