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

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

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

      干貨來襲!5 分鐘學會快速實現責任鏈,效率直接拉滿!

      在軟件開發的 “戰場” 上,我們常常會遭遇各種棘手的難題。其中,如何優雅地解耦請求的發送者與接收者,同時實現請求在多個處理者之間靈活、動態地流轉,一直是困擾眾多開發者的 “攔路虎”。這時,責任鏈模式如同一位 “救星”,強勢登場,為我們打開了高效處理請求的大門。在日常開發中,我們頻繁使用的過濾器、攔截器等功能,其背后都離不開責任鏈模式的強力支撐。然而,很多開發者一聽到要自己動手實現一個責任鏈,就會眉頭緊皺,仿佛面對一座難以逾越的高山。

      別害怕!今天就給大家帶來一款堪稱 “神器” 的工具 ——apache commons-chain。有了它,實現責任鏈將變得輕而易舉,就像擁有了一把萬能鑰匙,能夠輕松解鎖各種復雜的場景。不管你是經驗豐富的開發老手,還是剛剛踏入編程領域的新手小白,這款工具都能讓你在實現責任鏈的過程中事半功倍!

      一、commons-chain:責任鏈實現的 “超級外掛”

      commons-chain 是 apache commons 大家族中的重要一員,它就像是一個功能強大的 “超級外掛”,專門用于創建和管理命令對象。這些命令對象可不是普通的角色,它們各自擁有獨特的使命,就像一個個訓練有素的特種兵,隨時準備執行各種高難度任務。借助 commons-chain,開發者可以將多個命令以鏈式的方式巧妙地串聯起來,每個命令專注于完成自己的任務,完成后便如同接力賽中的運動員一樣,精準地將控制權傳遞給下一個命令,從而構建出一條高效、靈活的責任鏈。

      二、commons-chain 核心接口:構建責任鏈的 “秘密武器”

      Command 接口: 它是責任鏈中每一個具體任務的執行者,如同戰場上沖鋒陷陣的士兵。這個接口只有一個核心方法boolean execute(Context context),別看它簡單,卻蘊含著巨大的能量。當該方法返回true時,就像是吹響了停止的號角,責任鏈中的其他命令將停止執行;而返回false時,則意味著責任鏈可以繼續前進,執行后續的命令。不過,一旦執行過程中出現異常,就如同遭遇了突發狀況,責任鏈也會被迫中斷,后續命令將無法執行。

      Chain 接口: 它是責任鏈的組織者和管理者,就像是一位經驗豐富的指揮官,負責將各個命令有序地編排在一起。所有要在責任鏈中執行的命令,都需要先添加到這個 Chain 中。而且,它還實現了 Command 接口,這意味著 Chain 不僅能夠組織命令,自身也具備執行命令的能力,可謂是 “身兼數職”。

      Context 接口: 它是命令執行的上下文環境,如同一個信息共享的 “中央倉庫”,在整個責任鏈中傳遞著關鍵信息。各個命令可以通過它訪問和修改共享數據,實現不同命令之間的協同作戰。此外,它還實現了 Map 接口,就像一個靈活多變的百寶箱,能夠存儲各種類型的信息,方便命令隨時取用。

      Filter 接口: 它是一種特殊的 Command,擁有更強大的功能,就像是特種兵中的精英。除了繼承 Command 的execute方法外,它還新增了一個boolean postprocess(Context context, Exception exception)方法。commons chain 會在執行完 Filter 的execute方法之后,無論責任鏈以何種方式結束,都會接著執行postprocess方法。而且,execute方法的執行順序與 Filter 在 Chain 中出現的位置一致,而postprocess方法的執行順序則與之相反。postprocess方法的返回值根據異常對象來決定,有異常時返回false,否則返回true,這樣就能確保在最后能及時拋出異常,方便我們進行錯誤排查和處理。

      Catalog 接口: 它就像是一個命令的 “智能索引”,是一個邏輯命名的命令(或 Chain)集合。通過使用它,Command 的調用者無需了解具體實現 Command 的類名,只需通過名字就能像在圖書館中查找書籍一樣,輕松獲取所需的 Command 實例,大大提高了開發效率。

      三、使用示例:手把手教你快速上手

      1、項目中的pom引入commons-chain gav

      <dependency>
                  <groupId>commons-chain</groupId>
                  <artifactId>commons-chain</artifactId>
                  <version>${commons-chain.version}</version>
              </dependency>
      

      2、實現command

      這里以 Filter 為例,為大家展示如何實現具體的命令邏輯。下面分別實現了判斷飛翔、跳躍和跑步能力的命令,每個命令都有自己獨特的功能和邏輯:

      public class FlyCommand implements Filter {
      
          /**
           * 執行當前操作
           *
           * 此方法應由具體的操作實現類來覆蓋,以提供具體的操作邏輯
           * 它負責根據給定的上下文執行業務邏輯,并返回一個布爾值表示執行結果
           *
           * @param context 執行操作的上下文,包含操作所需的信息和環境設置
           * @return boolean 表示操作執行的結果,true表示成功,false表示失敗
           * @throws Exception 如果執行過程中發生錯誤,拋出異常
           */
          @Override
          public boolean execute(Context context) throws Exception {
              Object fly = context.get("flyEnabled");
              boolean flyEnabled = fly != null && "true".equalsIgnoreCase(fly.toString());
              System.out.println("擁有飛翔的能力:" + flyEnabled);
              return flyEnabled;
          }
      /**
       * 在飛行能力判斷完成后進行后處理
       *
       *
       * @param context 上下文環境,可能包含執行判斷飛行能力前后的相關環境信息
       * @param exception 在判斷飛行能力過程中可能發生的異常,如果沒有異常,則為null
       * @return boolean 表示飛行能力判斷是否成功完成如果沒有異常,則返回true,否則返回false
       */
      @Override
      public boolean postprocess(Context context, Exception exception) {
          System.out.println("判定飛翔能力完畢...");
          if(exception != null){
              System.out.println("執行異常:" + exception.getMessage());
          }
          return exception == null;
      }
      
      }
      
      
      public class JumpCommand implements Filter {
      
          /**
           * 執行當前操作
           *
           * 此方法應由具體的操作實現類來覆蓋,以提供具體的操作邏輯
           * 它負責根據給定的上下文執行業務邏輯,并返回一個布爾值表示執行結果
           *
           * @param context 執行操作的上下文,包含操作所需的信息和環境設置
           * @return boolean 表示操作執行的結果,true表示成功,false表示失敗
           * @throws Exception 如果執行過程中發生錯誤,拋出異常
           */
          @Override
          public boolean execute(Context context) throws Exception {
              Object jump = context.get("jumpEnabled");
              boolean jumpEnabled = jump != null && "true".equalsIgnoreCase(jump.toString());
              System.out.println("擁有跳躍的能力:" + jumpEnabled);
              return jumpEnabled;
          }
      
          /**
           * 在跳躍能力判斷完成后進行后處理
           *
           *
           * @param context 上下文環境,可能包含執行判斷跳躍能力前后的相關環境信息
           * @param exception 在判斷跳躍能力過程中可能發生的異常,如果沒有異常,則為null
           * @return boolean 表示跳躍能力判斷是否成功完成如果沒有異常,則返回true,否則返回false
           */
          @Override
          public boolean postprocess(Context context, Exception exception) {
              System.out.println("判定跳躍能力完畢...");
              if(exception != null){
                  System.out.println("執行異常:" + exception.getMessage());
              }
              return exception == null;
          }
      }
      
      
      public class RunCommand implements Filter {
      
          /**
           * 執行當前操作
           *
           * 此方法應由具體的操作實現類來覆蓋,以提供具體的操作邏輯
           * 它負責根據給定的上下文執行業務邏輯,并返回一個布爾值表示執行結果
           *
           * @param context 執行操作的上下文,包含操作所需的信息和環境設置
           * @return boolean 表示操作執行的結果,true表示成功,false表示失敗
           * @throws Exception 如果執行過程中發生錯誤,拋出異常
           */
          @Override
          public boolean execute(Context context) throws Exception {
              Object run = context.get("runEnabled");
              boolean runEnabled = run != null && "true".equalsIgnoreCase(run.toString());
              System.out.println("擁有跑步的能力:" + runEnabled);
              return runEnabled;
          }
      
          /**
           * 在跑步能力判斷完成后進行后處理
           *
           *
           * @param context 上下文環境,可能包含執行判斷跑步能力前后的相關環境信息
           * @param exception 在判斷跑步能力過程中可能發生的異常,如果沒有異常,則為null
           * @return boolean 表示跑步能力判斷是否成功完成如果沒有異常,則返回true,否則返回false
           */
          @Override
          public boolean postprocess(Context context, Exception exception) {
              System.out.println("判定跑步能力完畢...");
              if(exception != null){
                  System.out.println("執行異常:" + exception.getMessage());
              }
              return exception == null;
          }
      }
      

      3、將創建的command加入到chain中

      @Slf4j
      public class ChainTest {
      
          private Context data;
      
          @Before
          public void prepareData(){
              data = new ContextBase();
              data.put("flyEnabled", "false");
              data.put("jumpEnabled", "false");
              data.put("runEnabled", "false");
          }
      
      
      
          @Test
          public void testChain(){
      
              Chain chain = new ChainBase();
              chain.addCommand(new FlyCommand());
              chain.addCommand(new JumpCommand());
              chain.addCommand(new RunCommand());
      
              try {
                  chain.execute(data);
              } catch (Exception e) {
                  log.error("執行鏈路失敗",e);
              }
      
          }
          }
      

      運行并查看結果

      擁有飛翔的能力:false
      擁有跳躍的能力:false
      擁有跑步的能力:false
      判定跑步能力完畢...
      判定跳躍能力完畢...
      判定飛翔能力完畢...
      

      a、 如果要根據名字獲取command,則可以利用catalog

      @Test
          public void testCatalog(){
              Catalog catalog = new CatalogBase();
              catalog.addCommand("fly", new FlyCommand());
              catalog.addCommand("jump", new JumpCommand());
              catalog.addCommand("run", new RunCommand());
      
      
      
      
              Iterator names = catalog.getNames();
              while (names.hasNext()) {
                  try {
                      String name = (String) names.next();
                      catalog.getCommand(name).execute(data);
                  } catch (Exception e) {
                     log.error("執行鏈路失敗",e);
                  }
              }
      
      
      
          }
      

      運行并查看結果

      擁有飛翔的能力:false
      擁有跑步的能力:false
      擁有跳躍的能力:false
      

      四、與 spring 集成:強強聯合,打造無敵組合

      1、自定義激活chain注解

      @Target({java.lang.annotation.ElementType.TYPE})
      @Retention(RetentionPolicy.RUNTIME)
      @Documented
      @Import(ChainRegistrar.class)
      public @interface EnableChain {
      
      
      
          /**
           * Base packages to scan for annotated components.
           * attribute.
           */
          String[] basePackages() default {};
      }
      

      2、自定義chain掃描器

      public class ChainClassPathBeanDefinitionScanner extends ClassPathBeanDefinitionScanner {
          
          
          public ChainClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
              super(registry);
          }
      
      
      
          @Override
          protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
              AnnotationMetadata metadata = beanDefinition.getMetadata();
              String[] interfaceNames = metadata.getInterfaceNames();
              return interfaceNames.length > 0
                      && Arrays.stream(interfaceNames)
                      .anyMatch(interfaceName ->
                              Command.class.getName().equals(interfaceName)
                      || Filter.class.getName().equals(interfaceName));
          }
      
      
      }
      
      

      3、將掃描的command注冊到spring容器中

      public class ChainRegistrar implements ImportBeanDefinitionRegistrar {
          @Override
          public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
              Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(EnableChain.class.getName());
              String[] basePackages = (String[]) annotationAttributes.get("basePackages");
              System.out.println("basePackages:" + Arrays.toString(basePackages));
      
              ChainClassPathBeanDefinitionScanner chainClassPathBeanDefinitionScanner = new ChainClassPathBeanDefinitionScanner(registry);
              chainClassPathBeanDefinitionScanner.addIncludeFilter((metadataReader, metadataReaderFactory) -> true);
              chainClassPathBeanDefinitionScanner.scan(basePackages);
      
          }
      }
      
      

      4、編寫一個chain聚合器

      @RequiredArgsConstructor
      public class CommandDelegete implements Command, InitializingBean {
      
          private final ObjectProvider<List<Command>> commandObjectProvider;
      
          private final Chain chain = new ChainBase();
      
      
          @Override
          public boolean execute(Context context) throws Exception {
              return chain.execute(context);
          }
      
          @Override
          public void afterPropertiesSet() throws Exception {
              List<Command> commands = commandObjectProvider.getIfAvailable();
              if(CollectionUtil.isNotEmpty(commands)){
                  commands.forEach(chain::addCommand);
              }
      
          }
      }
      
      

      5、將chain聚合器注入到spring中

      @Configuration
      public class CommandAutoConfiguration {
      
      
          @Bean
          @ConditionalOnMissingBean
          public CommandDelegete commandDelegete(ObjectProvider<List<Command>> commandObjectProvider){
              return new CommandDelegete(commandObjectProvider);
      
          }
      
      
      }
      
      

      6、如何使用

      @RequiredArgsConstructor
      public class UserHandlerInterceptor implements HandlerInterceptor {
      
      
          private final CommandDelegete commandDelegete;
      
          @Autowired
          private ServletContext servletContext;
      
      
          @Override
          public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                  throws Exception {
              Context context = new ServletWebContext(servletContext, request, response);
              commandDelegete.execute(context);
      
              return true;
          }
      }
      

      總結

      commons-chain 就像是一位貼心的開發伙伴,在實現責任鏈的道路上,它能夠為我們節省大量的時間和精力,讓我們的開發工作變得更加輕松高效。盡管它已經進入維護期,但其中蘊含的設計思想和編程技巧依然值得我們深入學習和借鑒。如果你對 commons-chain 感興趣,想要深入了解更多細節,可以訪問官網:
      https://commons.apache.org/dormant/commons-chain/cookbook.html

      demo鏈接

      為了方便大家學習和實踐,這里提供了完整的 demo 鏈接:
      https://github.com/lyb-geek/springboot-learning/tree/master/springboot-chain
      如果這篇文章對你有所幫助,不妨點贊、轉發給身邊的小伙伴,讓更多的開發者受益于這個強大的工具!同時,也歡迎大家關注我們,獲取更多實用的技術干貨!

      posted @ 2025-07-29 09:26  Linyb極客之路  閱讀(20)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 成人网站国产在线视频内射视频| 成人国产精品免费网站| 国产精品成人av电影不卡| 成年午夜无码av片在线观看| 成人精品国产一区二区网| 午夜一区欧美二区高清三区| 中文字幕在线国产精品| 亚洲日韩乱码中文无码蜜桃| 人妻中文字幕亚洲精品| 在线观看特色大片免费视频| 亚洲国产中文在线有精品| 亚洲成av人片在www鸭子| 女人下边被添全过视频的网址| 99久久精品国产综合一区| 中文字幕在线国产精品| 无码成人精品区在线观看| 黄色大全免费看国产精品| 福利一区二区在线播放| 国产日韩欧美| 久久精品第九区免费观看| 国产愉拍精品手机| 久爱www人成免费网站| 7878成人国产在线观看| gogogo高清免费观看| 玩弄丰满少妇人妻视频| 国产一区二区三区四区色| 亚洲综合一区二区国产精品| 国产尤物精品自在拍视频首页| 精品一区二区中文字幕| 久久精品国产亚洲av品| 亚洲av色香蕉一区二区| 成人精品一区日本无码网| 久久99久久99精品免视看动漫| 无码国产精品成人| 鲁丝一区鲁丝二区鲁丝三区| 国产精品亚洲av三区色| 国产精品熟女亚洲av麻豆| 国产成人无码A区在线观| 夜夜爱夜鲁夜鲁很鲁| 亚洲国产中文字幕精品| 久久爱在线视频在线观看|