手写简易版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. 提前实例化单例对象 接上面的流程。

相关推荐

  1. 简易Spring IOC容器04学习

    2024-07-21 17:04:02       30 阅读
  2. 简易Spring IOC容器02学习

    2024-07-21 17:04:02       26 阅读
  3. 简易Spring IOC容器05学习

    2024-07-21 17:04:02       26 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-21 17:04:02       138 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-21 17:04:02       152 阅读
  3. 在Django里面运行非项目文件

    2024-07-21 17:04:02       128 阅读
  4. Python语言-面向对象

    2024-07-21 17:04:02       140 阅读

热门阅读

  1. 网络文件传输

    2024-07-21 17:04:02       27 阅读
  2. vue2获取视频时长

    2024-07-21 17:04:02       29 阅读
  3. mybatis中的useGeneratedKeys和keyProperty

    2024-07-21 17:04:02       26 阅读
  4. AI Agent的创新之路:AutoGen与LangGraph的比较

    2024-07-21 17:04:02       22 阅读
  5. Android笔试面试题AI答之Activity(3)

    2024-07-21 17:04:02       22 阅读
  6. 关闭终端后继续执行celery任务

    2024-07-21 17:04:02       25 阅读
  7. 学习C语言之 深入了解数据存储

    2024-07-21 17:04:02       21 阅读
  8. WordPress杂技

    2024-07-21 17:04:02       27 阅读
  9. 赞扬的10条原则

    2024-07-21 17:04:02       28 阅读
  10. WHAT - 贪心场景和算法实现

    2024-07-21 17:04:02       29 阅读
  11. 多级联动jquery-cxselect-js的使用

    2024-07-21 17:04:02       28 阅读