乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      你簡(jiǎn)歷不寫(xiě)精通嗎,你說(shuō)怎么把Bean塞到Spring容器?

       小傅哥 2021-12-13


      作者:小傅哥
      博客:https://

      沉淀、分享、成長(zhǎng),讓自己和他人都能有所收獲!😄

      一、前言

      小傅哥,你是怎么學(xué)習(xí)的?

      有很多初學(xué)編程或者碼了幾年CRUD磚的小伙伴問(wèn)我,該怎么學(xué)編程?感覺(jué)什么都不會(huì)怎么辦?感覺(jué)目前的公司沒(méi)有核心業(yè)務(wù)學(xué)到不東西呀!

      其實(shí)我可能和很大一部分的粉絲讀者都有類似的經(jīng)歷,在傳統(tǒng)類似外包的行業(yè)待過(guò)、從C#語(yǔ)言兩年開(kāi)發(fā)再面Java崗、新到互聯(lián)網(wǎng)職場(chǎng)感覺(jué)太多不會(huì)的技術(shù)棧等等。

      但可能最讓我在學(xué)習(xí)編程上受益的就是不斷的折騰這些技術(shù):

      1. 關(guān)于外包:在外包2年時(shí)還是C#開(kāi)發(fā),時(shí)而搞搞中繼器、IO板卡、PLC。但我仍舊喜歡大學(xué)時(shí)期學(xué)的Java語(yǔ)言,那么每天5:30下班回家后,就不斷的用Java語(yǔ)言把公司接觸到的C#工程做翻新。差不多1年的時(shí)間,把幾乎我接觸到的項(xiàng)目翻新了個(gè)遍,就是那個(gè)時(shí)候知道的Java還能做串口通信,還是蠻有意思的。
      2. 關(guān)于場(chǎng)景:其實(shí)很多程序員在一個(gè)相對(duì)較小的公司時(shí),學(xué)習(xí)的最大瓶頸是眼界問(wèn)題,不知道有什么技術(shù)、不知道有什么場(chǎng)景,更不知道自己不會(huì)啥。其實(shí)很多時(shí)候這都跟有關(guān)系,公司是沒(méi)有這樣的場(chǎng)景,但是你可以看博客、看論壇、看視頻,加各類技術(shù)群。如果遇到哪些發(fā)廣告的就退了,哪些好的留下,認(rèn)識(shí)一些人脈,相知一些基友,這在個(gè)過(guò)程總能有所收獲,你會(huì)隨著時(shí)間的推移嗅到各類技術(shù)棧、項(xiàng)目、經(jīng)驗(yàn)、心得、面試等等,當(dāng)你武裝好了自己,再出去面試也就沒(méi)那么難了。
      3. 關(guān)于開(kāi)始:時(shí)間少、要學(xué)的多,感覺(jué)自己就是一把小鐵鍬,要去挖蘇伊士運(yùn)河,不知道能從哪開(kāi)始。這個(gè)時(shí)候建議不要盲目的收藏幾個(gè)T的資料和視頻,先打開(kāi)xmind,選個(gè)好看的主題,開(kāi)始梳理自己的技術(shù)棧,看看自己會(huì)什么不會(huì)什么,在從這些不會(huì)的內(nèi)容里選出你最想學(xué)的,把要學(xué)的內(nèi)容在梳理出相應(yīng)的資料庫(kù)。好,那么這個(gè)時(shí)候你就可以開(kāi)始了,記住開(kāi)始是從一點(diǎn)點(diǎn)深入的,不要總想著一口吃個(gè)胖子。

      方向?qū)α?#xff0c;快是最大的障礙!,很多時(shí)候只要你能平心靜氣日積月累的學(xué)習(xí),其實(shí)就沒(méi)有什么不能克服的問(wèn)題。編程里又有什么非常難的東西嗎,大部分知識(shí)都是不知道就不會(huì)而已,知道了就很簡(jiǎn)單。

      二、面試題

      謝飛機(jī),小記!,簡(jiǎn)歷上我都寫(xiě)精通了,要個(gè)20K沒(méi)問(wèn)題,等著吧!

      面試官:謝飛機(jī),技術(shù)不錯(cuò)呀,都是精通,哦,有一個(gè)vb了解,沒(méi)事我們不用vb

      謝飛機(jī):還行,我學(xué)的多,你問(wèn)吧。

      面試官:嗯,自信了不少。那我們聊聊 Spring,你這個(gè)也寫(xiě)的精通。

      謝飛機(jī):來(lái)吧!

      面試官:你說(shuō),怎么把Bean塞到Spring容器?能說(shuō)說(shuō)它的過(guò)程嗎,你有過(guò)相關(guān)技術(shù)的使用嗎,應(yīng)用了什么場(chǎng)景?

      謝飛機(jī):嗯!?嗯,,好像,沒(méi)用過(guò)。我都是精通使用API,@Resource

      面試官:哦,@Resource,注解是Spring哪個(gè)模塊提供的?

      謝飛機(jī):我,,,再見(jiàn)!ヾ( ̄▽ ̄)

      三、代理Bean注冊(cè)到Spring容器

      Bean注冊(cè)

      • 關(guān)于Bean注冊(cè)的技術(shù)場(chǎng)景,在我們?nèi)粘S玫降募夹g(shù)框架中,MyBatis 是最為常見(jiàn)的。通過(guò)在使用 MyBatis 時(shí)都只是定義一個(gè)接口不需要寫(xiě)實(shí)現(xiàn)類,但是這個(gè)接口卻可以和配置的 SQL 語(yǔ)句關(guān)聯(lián),執(zhí)行相應(yīng)的數(shù)據(jù)庫(kù)操作時(shí)可以返回對(duì)應(yīng)的結(jié)果。那么這個(gè)接口與數(shù)據(jù)庫(kù)的操作就用到的 Bean 的代理和注冊(cè)。
      • 我們都知道類的調(diào)用是不能直接調(diào)用沒(méi)有實(shí)現(xiàn)的接口的,所以需要通過(guò)代理的方式給接口生成對(duì)應(yīng)的實(shí)現(xiàn)類。接下來(lái)再通過(guò)把代理類放到 Spring 的 FactoryBean 的實(shí)現(xiàn)中,最后再把這個(gè) FactoryBean 實(shí)現(xiàn)類注冊(cè)到 Spring 容器。那么現(xiàn)在你的代理類就已經(jīng)被注冊(cè)到 Spring 容器了,接下來(lái)就可以通過(guò)注解的方式注入到屬性中。

      按照這個(gè)實(shí)現(xiàn)方式,我們來(lái)操作一下,看看一個(gè) Bean 的注冊(cè)過(guò)程在代碼中是如何實(shí)現(xiàn)的。

      1. 定義接口

      public interface IUserDao {
      
          String queryUserInfo();
      
      }
      
      • 先定義一個(gè)類似 DAO 的接口,基本這樣的接口在使用 MyBatis 時(shí)還是非常常見(jiàn)的。后面我們會(huì)對(duì)這個(gè)接口做代理和注冊(cè)。

      2. 類代理實(shí)現(xiàn)

      ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
      Class<?>[] classes = {IUserDao.class};    
      
      InvocationHandler handler = (proxy, method, args) -> "你被代理了 " + method.getName();
      IUserDao userDao = (IUserDao) Proxy.newProxyInstance(classLoader, classes, handler); 
      
      String res = userDao.queryUserInfo();
      logger.info("測(cè)試結(jié)果:{}", res);
      
      • Java 本身的代理方式使用起來(lái)還是比較簡(jiǎn)單的,用法也很固定。
      • InvocationHandler 是個(gè)接口類,它對(duì)應(yīng)的實(shí)現(xiàn)內(nèi)容就是代理對(duì)象的具體實(shí)現(xiàn)。
      • 最后就是把代理交給 Proxy 創(chuàng)建代理對(duì)象,Proxy.newProxyInstance。

      3. 實(shí)現(xiàn)Bean工廠

      public class ProxyBeanFactory implements FactoryBean {
      
          @Override
          public Object getObject() throws Exception {
      
              ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
              Class[] classes = {IUserDao.class};
              InvocationHandler handler = (proxy, method, args) -> "你被代理了 " + method.getName();
      
              return Proxy.newProxyInstance(classLoader, classes, handler);
          }
      
          @Override
          public Class<?> getObjectType() {
              return IUserDao.class;
          } 
      
      }
      
      • FactoryBean 在 spring 起到著二當(dāng)家的地位,它將近有70多個(gè)小弟(實(shí)現(xiàn)它的接口定義),那么它有三個(gè)方法;
        • T getObject() throws Exception; 返回bean實(shí)例對(duì)象
        • Class<?> getObjectType(); 返回實(shí)例類類型
        • boolean isSingleton(); 判斷是否單例,單例會(huì)放到Spring容器中單實(shí)例緩存池中
      • 在這里我們把上面使用Java代理的對(duì)象放到了 getObject() 方法中,那么現(xiàn)在再?gòu)?Spring 中獲取到的對(duì)象,就是我們的代理對(duì)象了。

      4. Bean 注冊(cè)

      public class RegisterBeanFactory implements BeanDefinitionRegistryPostProcessor {
      
          @Override
          public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
      
              GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
              beanDefinition.setBeanClass(ProxyBeanFactory.class);
      
              BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(beanDefinition, "userDao");
              BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
          }
      
      }
      

      在 Spring 的 Bean 管理中,所有的 Bean 最終都會(huì)被注冊(cè)到類 DefaultListableBeanFactory 中,以上這部分代碼主要的內(nèi)容包括:

      • 實(shí)現(xiàn) BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry方法,獲取 Bean 注冊(cè)對(duì)象。
      • 定義 Bean,GenericBeanDefinition,這里主要設(shè)置了我們的代理類工廠。
      • 創(chuàng)建 Bean 定義處理類,BeanDefinitionHolder,這里需要的主要參數(shù);定義 Bean 和名稱 setBeanClass(ProxyBeanFactory.class)。
      • 最后將我們自己的bean注冊(cè)到spring容器中去,registry.registerBeanDefinition()

      四、測(cè)試驗(yàn)證

      在上面我們已經(jīng)把自定義代理的 Bean 注冊(cè)到了 Spring 容器中,接下來(lái)我們來(lái)測(cè)試下這個(gè)代理的 Bean 被如何調(diào)用。

      1. 定義 spring-config.xml

      <bean id="userDao" class="org.itstack.interview.bean.RegisterBeanFactory"/>
      
      • 這里我們把 RegisterBeanFactory 配置到 spring 的 xml 配置中,便于啟動(dòng)時(shí)加載。

      2. 單元測(cè)試

      @Test
      public void test_IUserDao() {
          BeanFactory beanFactory = new ClassPathXmlApplicationContext("spring-config.xml");
          IUserDao userDao = beanFactory.getBean("userDao", IUserDao.class);
          String res = userDao.queryUserInfo();
          logger.info("測(cè)試結(jié)果:{}", res);
      }
      

      測(cè)試結(jié)果

      22:53:14.759 [main] DEBUG o.s.c.e.PropertySourcesPropertyResolver - Could not find key 'spring.liveBeansView.mbeanDomain' in any property source
      22:53:14.760 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'userDao'
      22:53:14.796 [main] INFO  org.itstack.interview.test.ApiTest - 測(cè)試結(jié)果:你被代理了 queryUserInfo
      
      Process finished with exit code 0
      
      • 從測(cè)試結(jié)果可以看到,我們已經(jīng)可以通過(guò)注入到Spring的代理Bean對(duì)象,實(shí)現(xiàn)我們的預(yù)期結(jié)果。
      • 其實(shí)這個(gè)過(guò)程也是很多框架中用到的方式,尤其是在一些中間件開(kāi)發(fā),類似的 ORM 框架都需要使用到。

      五、總結(jié)

      • 本章節(jié)的內(nèi)容相對(duì)來(lái)說(shuō)非常并不復(fù)雜,只不過(guò)這一塊的代碼是我們從源碼的學(xué)習(xí)中提取出來(lái)的最核心流程,因?yàn)樵诖蟛糠挚蚣苤幸不径际沁@樣的進(jìn)行處理的。如果這樣的地方不了解,那么很難讀懂諸如此類的框架源碼,也很難理解它是怎么調(diào)用的。
      • 在本文中主要涉及到的技術(shù)點(diǎn)包括;代理、對(duì)象、注冊(cè),以及相應(yīng)的使用。尤其是 Bean 的定義 BeanDefinitionHolder 和 Bean 的注冊(cè) BeanDefinitionReaderUtils.registerBeanDefinition。
      • 如果你還能把此類技術(shù)聯(lián)想的更多,可以嘗試把代理的對(duì)象替換成數(shù)據(jù)庫(kù)的查詢對(duì)象,也就是對(duì) JDBC 的操作,當(dāng)你完成以后也就實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的 ORM 框架。其實(shí)很多技術(shù)實(shí)現(xiàn)都是由小做大,但最開(kāi)始的那部分是整個(gè)代碼實(shí)現(xiàn)的核心。

      六、系列推薦

      • 認(rèn)知自己的技術(shù)棧盲區(qū)
      • LinkedList插入速度比ArrayList快?你確定嗎?
      • 除了JDK、CGLIB,還有3種類代理方式?面試又卡住!
      • ReentrantLock之AQS原理分析和實(shí)踐使用
      • 咋嘞?你的IDEA過(guò)期了吧!加個(gè)Jar包就破解了,為什么?

        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多