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

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

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      • 前言(本文為原創(chuàng),轉(zhuǎn)載請注明出處)

        個人之前對于框架的學(xué)習(xí),就停留在配置,使用階段。說實話過段時間就會忘得蕩然無存。也不知道框架的運行邏輯,就是知道添加個注解,就可以用了。

        由于實習(xí),時間比較多,也感恩遇到個好老師,教并給我時間看源碼,雖然沒有做過多少業(yè)務(wù),但是感覺比做業(yè)務(wù)更有意義。慢慢的去跟代碼, 對Spring

        運行流程大致有個解。現(xiàn)分享給大家,不足之處,希望各位補充,相互學(xué)習(xí)。

      • 從源碼看Spring

        可能我們很少在意,ClassPathXmlApplicationContext這個類,其實這個類做了很多的事情,它才是我們了解Spring框架的窗戶。 

          ClassPathXmlApplicationContext c=new ClassPathXmlApplicationContext("ApplicationContext.xml");

       當(dāng)我們執(zhí)行上面的語句的時候,

        public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
        throws BeansException {
           super(parent);
         setConfigLocations(configLocations);
         if (refresh) {
         refresh();
         }
        }
      實際上走的是這個構(gòu)造函數(shù),這個構(gòu)造函數(shù)做了兩個事情,一是setConfigLocations()方法初始化一些配置。一是reFresh()函數(shù),該函數(shù)進行了Bean的注冊,事件廣播等。
      refresh()函數(shù)十分重要,具體干了什么,請看下面的源碼注釋:
         public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
         prepareRefresh();
              ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        prepareBeanFactory(beanFactory);
        try {
         // Allows post-processing of the bean factory in context subclasses.
         postProcessBeanFactory(beanFactory);
        // 注冊Bean.
         invokeBeanFactoryPostProcessors(beanFactory);
        // 登記攔截bean創(chuàng)建的處理器
         registerBeanPostProcessors(beanFactory);
        initMessageSource();
         // 創(chuàng)建了一個廣播事件的類
        initApplicationEventMulticaster();
        onRefresh();
        // 注冊事件監(jiān)聽者
        registerListeners();
        // 實例化那些被配置成單例的Bean
        finishBeanFactoryInitialization(beanFactory);
        // 結(jié)束刷新,實際上就是廣播事件等操作
         finishRefresh();
        }
         catch (BeansException ex) {
         // Destroy already created singletons to avoid dangling resources.
        destroyBeans();
        // Reset 'active' flag.
        cancelRefresh(ex);
        // Propagate exception to caller.
        throw ex;
         }
        }
        }
       先對Spring框架的事件機制簡單的做個擴展,常規(guī)來看事件涉及如下幾方:
        1)事件本身(生產(chǎn)者)
        2)消費事件者
        3)事件管理(訂閱中心)
       1.Spring事件本身從ApplicationEvent派生,事件消費者為ApplicationListener<T extends ApplicationEvent>,事件管理中心為ApplicationEventMulticaster
        它負責(zé)管理監(jiān)聽者等。
       2.Spring當(dāng)廣播一個事件時,它首先去查找該事件的監(jiān)聽者,然后再去遍歷監(jiān)聽者調(diào)用其onApplicationEvent(Application evnet)接口,將事件傳給監(jiān)聽者。
        最后當(dāng)我們調(diào)用getBean()的時候,實際上經(jīng)過refresh()的bean注冊,已經(jīng)被緩存到map里面,直接出map里面取出實例化即可。

      • 代碼簡易實現(xiàn)Spring
           

       

        上面的工程目錄結(jié)構(gòu)為com.springImpl.annotion放的spring的注解類。com.springImple.core放得實現(xiàn)Spring框架的核心類。com.springImpl.test放的是測試類。

        1)注解類:

         假設(shè)現(xiàn)在我這個框架還是比較搓,就一個注解,

          import java.lang.annotation.*;
          @Documented
          @Retention(RetentionPolicy.RUNTIME)
          @Target(ElementType.FIELD)//為了書寫簡單 這里只作用于屬性 也就是域 成員變量
          public @interface Resources {
          }

         2)事件類:

         現(xiàn)在這個事件就是一個約定,實際啥也沒有     

          public class ApplicationEvent {
          }

        3)監(jiān)聽者類  

          public interface ApplicationListener<T extends ApplicationEvent> {
          void onApplicationEvent(T event);
          }

        4)事件訂閱中心類

          public interface ApplicationEventMulticaster {
           void publishEvent(ApplicationEvent event);
          }

        5)解析配置文件的類

          public class ConfigResolver extends ApplicationEvent implements ApplicationEventMulticaster{
          private String configXml="spring.xml";
          static HashMap<String ,Object> BeanFactory;//這里就是模仿beanFactory 將所有的bean用beanid與對應(yīng)實例用map保存起來
          static HashMap<String ,ApplicationListener> RegistryListener;//這里保存那些是監(jiān)聽者的bean
          static {
          BeanFactory=new HashMap<>();
          RegistryListener=new HashMap<>();
          }
          public ConfigResolver(String config){
          configXml=config==null?configXml:config;//默認就是spring.xml
          setConfigLocations(configXml);
          refresh();
          }
           public Object getBean(String beanId){
          return BeanFactory.get(beanId);
           }
           private void setConfigLocations(String configXml){
          //什么都不做 當(dāng)然可以做一些環(huán)境的檢查 將配置的提取用一個類去處理等等 我這偷個懶
          }
          private void refresh(){
          //注冊bean
          invokeBeanFactoryPostProcessors(BeanFactory);
          //登記監(jiān)聽者
          registerListeners();
          //j結(jié)束刷新 表面程序已經(jīng)啟動 可以廣播這個刷新完畢事件了 廣播事件
          finishRefresh();
          }
          private void finishRefresh(){
          publishEvent(this);
        }

           /**
           * 從beanfactory找到那些是監(jiān)聽者類型的bean
           */
          private void registerListeners(){
          Iterator<String> it=BeanFactory.keySet().iterator();
          while(it.hasNext()){
          String key=it.next();
          if(BeanFactory.get(key) instanceof ApplicationListener){
           RegistryListener.put(key,(ApplicationListener)BeanFactory.get(key));
           it.remove();
          }
          }
           }

           /**
          * 將配置文件中的bean全部實例化到map里面
          * @param beanFactory
          */
           private void invokeBeanFactoryPostProcessors(HashMap beanFactory){

          InputStream in= null;
          try {
           in = ConfigResolver.class.getResourceAsStream(configXml)==null?
                    new FileInputStream(configXml):ConfigResolver.class.getResourceAsStream(configXml);//兼容資源路徑 與 絕對路徑
          } catch (FileNotFoundException e) {
           e.printStackTrace();
           }
          try {
           DocumentBuilder db=DocumentBuilderFactory.newInstance().newDocumentBuilder();
          Document dc=db.parse(in);
          NodeList nl=dc.getElementsByTagName("bean");
          for(int i=0;i<nl.getLength();i++){
          NamedNodeMap attrs= nl.item(i).getAttributes();
           HashMap<String,String> beanMap=new HashMap<>();//對應(yīng)一個bean標簽
          for(int j=0;j<attrs.getLength();j++){
          String beanNodeName=attrs.item(j).getNodeName();
          String beanNodeValue=null;
          if(beanNodeName!=null) {
          beanNodeValue = attrs.item(j).getNodeValue();
          }
          if(beanNodeValue!=null){
           beanMap.put(beanNodeName,beanNodeValue);
           }
          }
           String beanId=beanMap.get("id");
          String beanClass=beanMap.get("class");
          if(beanClass==null||beanId==null){
           continue;
           }
           try {
           Class cls=Class.forName(beanClass);
           Object beanObject=cls.newInstance();
          Field[] fds=beanObject.getClass().getDeclaredFields();
          for(Field fd:fds){
          fd.setAccessible(true);//獲取訪問私有變量權(quán)限
          Resources rs=fd.getAnnotation(Resources.class);
          if(rs!=null){
           fd.set(beanObject,fd.getType().newInstance());//實例化帶有Resource注解的成員
          }
          }
          beanFactory.put(beanId,beanObject);//將bean放到map
          } catch (ClassNotFoundException e) {
           e.printStackTrace();
          } catch (IllegalAccessException e) {
           e.printStackTrace();
          } catch (InstantiationException e) {
           e.printStackTrace();
          }
           }
           } catch (ParserConfigurationException e) {
           e.printStackTrace();
           } catch (SAXException e) {
           e.printStackTrace();
          } catch (IOException e) {
           e.printStackTrace();
           }
           }

          /**
          * 廣播事件
           * @param event
           */
           @Override
           public void publishEvent(ApplicationEvent event) {
          Iterator<String> it=RegistryListener.keySet().iterator();
          while(it.hasNext()){
          RegistryListener.get(it.next()).onApplicationEvent(event);
          }
          }
          }
        6)看一下測試類:
          //監(jiān)聽程序啟動的類 監(jiān)聽者
          public class ApplicationStartLister implements ApplicationListener<ApplicationEvent> {
           @Override
           public void onApplicationEvent(ApplicationEvent event) {
           System.out.println("SpringImpl App start");
          }
          }
        
          //假設(shè)這里有個眼瞎的人 他用注解注注入了個眼睛Ege類
          public class Blind {
          @Resources
          private Ege ege;
           public Ege getEge(){
          return ege;
           }
          }
          //眼睛Ege類
          public class Ege {
           public String see(){
          return "the world is so beautiful.";
          }
          }

          //主程序
           public class DoMain {
              public static void main(String []args){
           ConfigResolver cfg=new ConfigResolver("E:\\__Java\\__idea_proj\\SpringImpl\\src\\resources\\spring.xml");
           Blind b= (Blind) cfg.getBean("mybean");
           System.out.println("tell me how is the world :"+b.getEge().see());
           }
          }
          //配置文件

                        

         7)運行結(jié)果

            

                        

        到此完畢,一個簡單的模仿spring框架完畢。

       







      posted on 2017-08-19 23:18  泥粑  閱讀(5707)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 国产精品久久毛片| 国内精品伊人久久久久777| 国精品无码一区二区三区在线| 国产精品自拍自在线播放| 亚洲成人av在线高清| 滨州市| 亚洲乱码中文字幕小综合| 亚洲男女羞羞无遮挡久久丫| 最新精品露脸国产在线| 一本加勒比hezyo无码人妻| 国产一区二区av天堂热| 亚洲欧美一区二区成人片| 亚洲综合色区另类av| 亚洲精品国产aⅴ成拍色拍| 怡红院一区二区三区在线| 国产精品国语对白一区二区| 最新的国产成人精品2022| av天堂久久天堂av| 亚洲成av人片在www鸭子| 亚洲热妇无码av在线播放| 丰满人妻无码∧v区视频| 在线涩涩免费观看国产精品| 成人av天堂网在线观看| 亚洲老妇女亚洲老熟女久| 日韩精品视频一区二区不卡| 亚洲aⅴ男人的天堂在线观看| 久久精品午夜视频| 日日躁夜夜躁狠狠躁超碰97| 中文人妻熟妇乱又伦精品| 丰满少妇在线观看网站| 韩国av无码| 亚洲中少妇久久中文字幕| 成人啪精品视频网站午夜| 久久亚洲精品11p| 尤物yw193无码点击进入 | 国语自产拍精品香蕉在线播放| 亚洲AV国产福利精品在现观看| 俄罗斯老熟妇性爽xxxx| 色色97| 亚洲香蕉伊综合在人在线| 欧美一本大道香蕉综合视频|