<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      手寫Spring框架-貳

      前言

      前面已經(jīng)實(shí)現(xiàn)了給類對(duì)象添加了修改注冊(cè)Bean定義未實(shí)例化前的屬性信息修改和初始化過程中的前置和后置處理,
      本章實(shí)現(xiàn)Bean的初始化和銷毀方法、Aware感知容器、擴(kuò)展FactoryBean

      正文

      初始化和銷毀方法

      定義初始化和銷毀方法的接口

      public interface InitializingBean {
          /**
           * Bean處理了屬性填充后調(diào)用
           * @throws Exception
           */
          void afterPropertiesSet() throws Exception;
      }
      
      public interface DisposableBean {
          void destroy() throws Exception;
      }
      

      定義銷毀方法適配器

      @Data
      public class DisposableBeanAdapter implements DisposableBean {
          private final Object bean;
          private final String beanName;
          private String destroyMethodName;
      
          public DisposableBeanAdapter(Object bean, String beanName, BeanDefinition beanDefinition) {
              this.bean = bean;
              this.beanName = beanName;
              this.destroyMethodName = beanDefinition.getDestroyMethodName();
          }
      
          @Override
          public void destroy() throws Exception {
              // 1. 實(shí)現(xiàn)接口 DisposableBean
              if(bean instanceof DisposableBean) {
                  ((DisposableBean) bean).destroy();
              }
      
              // 2. 如果 BeanDefinition 配置了 destroy-method,再通過反射調(diào)用
              //    但如果同時(shí)實(shí)現(xiàn)了 DisposableBean 且配置的名字剛好就是 "destroy",則跳過,避免重復(fù)調(diào)用
              if (StrUtil.isNotEmpty(destroyMethodName)
                      && !(bean instanceof DisposableBean && "destroy".equals(this.destroyMethodName))) {
                  Method destroyMethod = bean.getClass().getMethod(destroyMethodName);
                  if (null == destroyMethod) {
                      throw new BeansException("Couldn't find a destroy method named '" + destroyMethodName + "' on bean with name '" + beanName + "'");
                  }
                  destroyMethod.invoke(bean);
              }
          }
      }
      

      在初始化時(shí)調(diào)用初始化方法和注冊(cè)銷毀方法,修改AbstractAutowireCapableBeanFactory抽象類的createBean方法

      public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
      
          private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
      
          @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);
                  // 執(zhí)行 Bean 的初始化方法和 BeanPostProcessor 的前置和后置處理方法
                  bean = initializeBean(beanName, bean, beanDefinition);
              } catch (Exception e) {
                  throw new BeansException("Instantiation of bean failed", e);
              }
      
              // 注冊(cè)實(shí)現(xiàn)了 DisposableBean 接口的 Bean 對(duì)象
              registerDisposableBeanIfNecessary(beanName, bean, beanDefinition);
      
              addSingleton(beanName, bean);
              return bean;
          }
      
          protected void registerDisposableBeanIfNecessary(String beanName, Object bean, BeanDefinition beanDefinition) {
              if (bean instanceof DisposableBean || StrUtil.isNotEmpty(beanDefinition.getDestroyMethodName())) {
                  registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, beanDefinition));
              }
          }
      
      }
      

      添加虛擬機(jī)關(guān)閉鉤子注冊(cè)調(diào)用銷毀方法

      public interface ConfigurableApplicationContext extends ApplicationContext {
      
          void refresh() throws BeansException;
      
          void registerShutdownHook();
      
          void close();
      
      }
      
      public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
      
          // ...
      
          @Override
          public void registerShutdownHook() {
              Runtime.getRuntime().addShutdownHook(new Thread(this::close));
          }
      
          @Override
          public void close() {
              getBeanFactory().destroySingletons();
          }
      
      }
      

      Aware感知容器

      定義Aware接口
      標(biāo)記性接口,實(shí)現(xiàn)該接口可以被spring容器感知

      public interface Aware {
      }
      

      實(shí)現(xiàn)容器感知類

      public interface BeanNameAware extends Aware{
          void setBeanName(String beanName);
      }
      
       public interface BeanFactoryAware extends Aware{
          void setBeanFactory(BeanFactory beanFactory) throws BeansException;
      } 
      
      public interface BeanClassLoaderAware extends Aware{
          void setBeanClassLoader(ClassLoader classLoader);
      }
      
      public interface ApplicationContextAware extends Aware {
          void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
      }
      

      由于這些接口需要的東西(BeanName、ClassLoader、BeanFactory)在 BeanFactory 內(nèi)部就能直接拿到,不依賴 ApplicationContext。
      而且這幾個(gè)是 基礎(chǔ)級(jí)別 的 Aware 回調(diào),Spring 在最核心的 AbstractAutowireCapableBeanFactory.initializeBean 里就直接處理了,保證所有 Bean 都能拿到這些最底層的元信息。

      而這些接口需要的對(duì)象(ApplicationContext、Environment 等)并不是 BeanFactory 自身能提供的,而是只有在 ApplicationContext 級(jí)別才有的上下文信息。
      所以,需要專門寫了一個(gè) ApplicationContextAwareProcessor,實(shí)現(xiàn)了 BeanPostProcessor,在 postProcessBeforeInitialization 階段給這些 Bean 注入。

      public class ApplicationContextAwareProcessor implements BeanPostProcessor {
          private final ApplicationContext applicationContext;
      
          public ApplicationContextAwareProcessor(ApplicationContext applicationContext) {
              this.applicationContext = applicationContext;
          }
      
          @Override
          public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
              if(bean instanceof ApplicationContextAware) {
                  ((ApplicationContextAware) bean).setApplicationContext(applicationContext);
              }
              return bean;
          }
      
          @Override
          public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
              return bean;
          }
      }
      

      擴(kuò)展FactoryBean

      因?yàn)槲覀冊(cè)谑褂?Spring、MyBatis 框架的時(shí)候都可以知道,并沒有手動(dòng)的去創(chuàng)建任何操作數(shù)據(jù)庫的 Bean 對(duì)象,
      有的僅僅是一個(gè)接口定義,而這個(gè)接口定義竟然可以被注入到其他需要使用 Dao 的屬性中去了,那么這一過程最核心待解決的問題,
      就是需要完成把復(fù)雜且以代理方式動(dòng)態(tài)變化的對(duì)象,注冊(cè)到 Spring 容器中。而為了滿足這樣的一個(gè)擴(kuò)展組件開發(fā)的需求,就需要我們?cè)诂F(xiàn)有手寫的 Spring 框架中,添加這一能力。

      定義FactoryBean接口

      public interface FactoryBean<T> {
          T getObject() throws Exception;
      
          Class<?> getObjectType();
      
          boolean isSingleton();
      }
      

      實(shí)現(xiàn)FactoryBean注冊(cè)服務(wù)

      public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry{
      
          private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>();
      
          protected Object getCachedObjectForFactoryBean(String beanName) {
              Object object = this.factoryBeanObjectCache.get(beanName);
              return (object != NULL_OBJECT ? object : null);
          }
      
          protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName) {
              if(factory.isSingleton()){
                  Object object = this.getCachedObjectForFactoryBean(beanName);
                  if(object == null){
                      object = this.doGetObjectFromFactoryBean(factory, beanName);
                      this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
                  }
                  return (object != NULL_OBJECT ? object : null);
              }else{
                  return this.doGetObjectFromFactoryBean(factory, beanName);
              }
          }
      
          private Object doGetObjectFromFactoryBean(final FactoryBean factory, final String beanName){
              try {
                  return factory.getObject();
              } catch (Exception e) {
                  throw new BeansException("FactoryBean threw exception on object[" + beanName + "] creation", e);
              }
          }
      }
      

      擴(kuò)展 AbstractBeanFactory 創(chuàng)建對(duì)象邏輯
      首先這里把 AbstractBeanFactory 原來繼承的 DefaultSingletonBeanRegistry,修改為繼承 FactoryBeanRegistrySupport。
      因?yàn)樾枰獢U(kuò)展出創(chuàng)建 FactoryBean 對(duì)象的能力,所以這就想一個(gè)鏈條服務(wù)上,截出一個(gè)段來處理額外的服務(wù),并把鏈條再鏈接上。
      此處新增加的功能主要是在 doGetBean 方法中,添加了調(diào)用 (T) getObjectForBeanInstance(sharedInstance, name) 對(duì)獲取 FactoryBean 的操作。
      在 getObjectForBeanInstance 方法中做具體的 instanceof 判斷,另外還會(huì)從 FactoryBean 的緩存中獲取對(duì)象,如果不存在則調(diào)用 FactoryBeanRegistrySupport#getObjectFromFactoryBean,執(zhí)行具體的操作

      public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
      
          protected <T> T doGetBean(final String name, final Object[] args) {
              Object sharedInstance = getSingleton(name);
              if (sharedInstance != null) {
                  // 如果是 FactoryBean,則需要調(diào)用 FactoryBean#getObject
                  return (T) getObjectForBeanInstance(sharedInstance, name);
              }
      
              BeanDefinition beanDefinition = getBeanDefinition(name);
              Object bean = createBean(name, beanDefinition, args);
              return (T) getObjectForBeanInstance(bean, name);
          }  
         
          private Object getObjectForBeanInstance(Object beanInstance, String beanName) {
              if (!(beanInstance instanceof FactoryBean)) {
                  return beanInstance;
              }
      
              Object object = getCachedObjectForFactoryBean(beanName);
      
              if (object == null) {
                  FactoryBean<?> factoryBean = (FactoryBean<?>) beanInstance;
                  object = getObjectFromFactoryBean(factoryBean, beanName);
              }
      
              return object;
          }
              
          // ...
      }
      
      posted @ 2025-09-03 17:01  憂傷丶情語  閱讀(12)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 97超级碰碰碰久久久久app| 五华县| 中字幕人妻一区二区三区| 自拍偷拍一区二区三区四| 老妇肥熟凸凹丰满刺激| 四虎成人精品在永久免费| 翘臀少妇被扒开屁股日出水爆乳| 久久精品国产中文字幕| 国产AV福利第一精品| 五月天天天综合精品无码| 国产偷国产偷亚洲高清午夜| 国产精品无码素人福利不卡| 国产精品va在线观看无码不卡| 天干天干天啪啪夜爽爽99| 国产午夜福利一区二区三区| 中国女人高潮hd| 人妻系列无码专区免费| 成人免费无码av| 亚洲av综合av一区| 亚洲国产成人va在线观看天堂| 久久久午夜精品福利内容| 日韩av色一区二区三区| 亚洲 欧美 动漫 少妇 自拍| 在线a人片免费观看| 色欲综合久久中文字幕网| 奇米影视7777狠狠狠狠色| 国产精品一区二区在线欢| 最新国产精品好看的精品| 龙泉市| 武装少女在线观看高清完整版免费| 曰韩无码av一区二区免费| 亚洲精品一区二区三区综合| 中文字幕国产精品综合| 亚洲人妻精品中文字幕| 亚洲国产精品线观看不卡| 亚洲欧洲∨国产一区二区三区| 国产精品∧v在线观看| 崇阳县| 国产激情艳情在线看视频| 国内精品免费久久久久电影院97| 久久影院午夜伦手机不四虎卡|