亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

使用自定義注解和@Aspect實(shí)現(xiàn)責(zé)任鏈模式的組件增強(qiáng)的詳細(xì)代碼

 更新時(shí)間:2023年05月21日 09:25:59   作者:程序員的思考與落地  
責(zé)任鏈模式是一種行為設(shè)計(jì)模式,其作用是將請(qǐng)求的發(fā)送者和接收者解耦,從而可以靈活地組織和處理請(qǐng)求,本文講給大家介紹如何使用自定義注解和@Aspect實(shí)現(xiàn)責(zé)任鏈模式的組件增強(qiáng),文中有詳細(xì)的代碼示例供大家參考,感興趣的同學(xué)可以借鑒一下

責(zé)任鏈模式

責(zé)任鏈模式是一種行為設(shè)計(jì)模式,其作用是將請(qǐng)求的發(fā)送者和接收者解耦,從而可以靈活地組織和處理請(qǐng)求。它通過(guò)將請(qǐng)求沿著一個(gè)由多個(gè)處理器組成的鏈路進(jìn)行傳遞和處理,直到有一個(gè)處理器能夠處理該請(qǐng)求或者鏈路的末端。

該模式的主要作用是:

  • 解耦請(qǐng)求發(fā)送者和接收者:責(zé)任鏈模式將發(fā)送者和接收者解耦,發(fā)送者無(wú)需知道具體是哪個(gè)接收者來(lái)處理請(qǐng)求,接收者也無(wú)需知道請(qǐng)求的發(fā)送者是誰(shuí),從而提高系統(tǒng)的靈活性和可維護(hù)性。

  • 動(dòng)態(tài)組織和處理請(qǐng)求:責(zé)任鏈模式可以動(dòng)態(tài)地組織和處理請(qǐng)求,可以根據(jù)實(shí)際情況靈活地調(diào)整鏈路上的處理器順序和數(shù)量,實(shí)現(xiàn)不同的業(yè)務(wù)邏輯和處理策略。

  • 避免請(qǐng)求的硬編碼:責(zé)任鏈模式通過(guò)配置和鏈路的方式來(lái)處理請(qǐng)求,避免了請(qǐng)求的硬編碼,使得系統(tǒng)更易于擴(kuò)展和維護(hù)。

應(yīng)用場(chǎng)景:

  • 請(qǐng)求的處理涉及多個(gè)環(huán)節(jié)或多個(gè)對(duì)象:當(dāng)一個(gè)請(qǐng)求需要經(jīng)過(guò)多個(gè)處理環(huán)節(jié)或者多個(gè)對(duì)象來(lái)處理時(shí),可以使用責(zé)任鏈模式。例如,請(qǐng)求的處理需要經(jīng)過(guò)驗(yàn)證、日志記錄、緩存等多個(gè)處理器進(jìn)行處理。

  • 動(dòng)態(tài)選擇處理器:當(dāng)處理器的選擇和順序需要根據(jù)實(shí)際情況進(jìn)行動(dòng)態(tài)調(diào)整時(shí),可以使用責(zé)任鏈模式。例如,根據(jù)請(qǐng)求的類(lèi)型或者優(yōu)先級(jí)來(lái)動(dòng)態(tài)選擇處理器。

  • 需要對(duì)請(qǐng)求進(jìn)行過(guò)濾或攔截的場(chǎng)景:當(dāng)需要對(duì)請(qǐng)求進(jìn)行過(guò)濾、攔截或者根據(jù)條件決定是否進(jìn)行處理時(shí),可以使用責(zé)任鏈模式。例如,對(duì)請(qǐng)求進(jìn)行權(quán)限驗(yàn)證、安全檢查、數(shù)據(jù)校驗(yàn)等操作。

  • 減少耦合,提高系統(tǒng)的靈活性和可維護(hù)性:當(dāng)需要降低發(fā)送者和接收者之間的耦合度,以及提高系統(tǒng)的靈活性和可維護(hù)性時(shí),可以考慮使用責(zé)任鏈模式。

總之,責(zé)任鏈模式適用于處理請(qǐng)求鏈路較長(zhǎng)、處理器之間松耦合、需要?jiǎng)討B(tài)組織和處理請(qǐng)求的場(chǎng)景。它可以幫助我們實(shí)現(xiàn)更靈活、可擴(kuò)展和可維護(hù)的系統(tǒng)設(shè)計(jì)。

實(shí)踐案例

下面結(jié)合自定義注解和@Aspect,我們可以實(shí)現(xiàn)對(duì)組件的增強(qiáng),使其具備責(zé)任鏈模式的功能。

首先,我們需要定義一個(gè)自定義注解,用于標(biāo)識(shí)需要應(yīng)用責(zé)任鏈模式的方法或類(lèi)??梢远x如下注解:

package com.example.demo.design.chain;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyChain {}

接下來(lái),我們使用@Aspect注解創(chuàng)建一個(gè)切面類(lèi),在切面類(lèi)中實(shí)現(xiàn)責(zé)任鏈模式的邏輯??梢远x如下切面類(lèi)

package com.example.demo.design.chain;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.List;

@Aspect
@Component
public class ChainHandlerAspect implements InitializingBean {
    @Autowired
    // 注入所有實(shí)現(xiàn)ChainHandler接口的責(zé)任鏈處理器
    private List<ChainHandler> chainHandlers;

    // 責(zé)任鏈的頭節(jié)點(diǎn)
    private ChainHandler chainHandler;

    @Around("@annotation(com.example.demo.design.chain.MyChain)")
    public Object checkParam(ProceedingJoinPoint pjp) throws Throwable {
        Object[] args = pjp.getArgs(); // 獲取方法的所有參數(shù)
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        Class<?>[] parameterTypes = method.getParameterTypes(); // 獲取方法的參數(shù)類(lèi)型列表

        for (int i = 0; i < parameterTypes.length; i++) {
            if (parameterTypes[i].getName().equals("java.lang.String")) {
                chainHandler.handle(new Request((String) args[0]));
            }
        }
        return pjp.proceed();
    }

    /**
     * 構(gòu)建處理器鏈
     */
    private ChainHandler buildHandlerChain() {
        ChainHandler headChainHandler = null;
        ChainHandler currentChainHandler = null;
        for (ChainHandler chainHandler : chainHandlers) {
            if (headChainHandler == null) {
                headChainHandler = chainHandler;
                currentChainHandler = headChainHandler;
            } else {
                currentChainHandler.setNextHandler(chainHandler);
                currentChainHandler = chainHandler;
            }
        }
        return headChainHandler;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // 構(gòu)建責(zé)任鏈
        chainHandler = this.buildHandlerChain();
    }
}

責(zé)任鏈相關(guān)組件

處理器接口

package com.example.demo.design.chain;

public interface ChainHandler {
    void handle(Request request);

    void setNextHandler(ChainHandler handler);
}

處理器實(shí)現(xiàn)類(lèi)

package com.example.demo.design.chain;

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Order(1)
public class FirstHandler implements ChainHandler {
    private ChainHandler nextHandler;

    @Override
    public void handle(Request request) {
        // 處理請(qǐng)求
        System.out.println("FirstHandler handling request " + request);

        // 將請(qǐng)求傳遞給下一個(gè)處理器
        if (nextHandler != null) {
            nextHandler.handle(request);
        }
    }

    @Override
    public void setNextHandler(ChainHandler handler) {
        this.nextHandler = handler;
    }
}
package com.example.demo.design.chain;

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Order(2)
public class SecondHandler implements ChainHandler {
    private ChainHandler nextHandler;

    @Override
    public void handle(Request request) {
        // 處理請(qǐng)求
        System.out.println("SecondHandler handling request " + request);

        // 將請(qǐng)求傳遞給下一個(gè)處理器
        if (nextHandler != null) {
            nextHandler.handle(request);
        }
    }

    @Override
    public void setNextHandler(ChainHandler handler) {
        this.nextHandler = handler;
    }
}
package com.example.demo.design.chain;

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Order(3)
public class ThirdHandler implements ChainHandler {
    private ChainHandler nextHandler;

    @Override
    public void handle(Request request) {
        // 處理請(qǐng)求
        System.out.println("ThirdHandler handling request " + request);
    }

    @Override
    public void setNextHandler(ChainHandler handler) {
        this.nextHandler = handler;
    }
}

以上代碼是類(lèi)同的,通過(guò)@Order注解指定了處理器的執(zhí)行順序,數(shù)字越小,優(yōu)先級(jí)越高。

setNextHandler方法用于設(shè)置下一個(gè)處理器,接收一個(gè)ChainHandler對(duì)象作為參數(shù),并將其保存在nextHandler字段中。

Request類(lèi)

package com.example.demo.design.chain;

public class Request {
    private String data;

    public Request(String data) {
        this.data = data;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return "Request{" +
                "data='" + data + ''' +
                '}';
    }
}

業(yè)務(wù)代碼組件

package com.example.demo.design.chain;

import org.springframework.stereotype.Component;

@Component
public class BizComponent {
    @MyChain
    public void process(String data) {
        System.out.println(data);
    }
}

@MyChain注解用于標(biāo)記需要應(yīng)用責(zé)任鏈模式的方法或類(lèi)。

啟動(dòng)類(lèi)

package com.example.demo.design.chain;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@SpringBootApplication
@EnableAspectJAutoProxy
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(com.example.demo.design.chain.Application.class, args);
    }
}

@EnableAspectJAutoProxy注解用于啟用AspectJ自動(dòng)代理功能,使得Spring能夠識(shí)別和應(yīng)用切面。

package com.example.demo.design.chain;

import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
@Data
public class ComponentRunner implements CommandLineRunner {

    @Autowired
    private BizComponent bizComponent;

    @Override
    public void run(String... args) throws Exception {
        // 執(zhí)行某個(gè)方法(帶Chain注解)
        bizComponent.process("Hello world!");
    }
}

該組件類(lèi)的執(zhí)行邏輯是在應(yīng)用程序啟動(dòng)后自動(dòng)執(zhí)行的,可以根據(jù)實(shí)際需求,在run方法中編寫(xiě)適當(dāng)?shù)臉I(yè)務(wù)邏輯和處理流程。

主要是為了模擬發(fā)起請(qǐng)求,可以使用Controller訪問(wèn)的方式。

**執(zhí)行效果 **

我們可以看到,在執(zhí)行bizComponent.process("Hello world!")之前,我們已經(jīng)被注解@MyChain進(jìn)行增強(qiáng)處理了,所以會(huì)經(jīng)過(guò)責(zé)任鏈進(jìn)行前置處理。

總結(jié)

通過(guò)這種方式,我們可以靈活地?cái)U(kuò)展和定制責(zé)任鏈的處理邏輯,通過(guò)注解和AOP的方式將責(zé)任鏈與業(yè)務(wù)組件進(jìn)行解耦,實(shí)現(xiàn)組件的增強(qiáng)和復(fù)用。

責(zé)任鏈模式的應(yīng)用場(chǎng)景很廣泛,例如在Web開(kāi)發(fā)中,可以使用責(zé)任鏈模式來(lái)處理請(qǐng)求的攔截、驗(yàn)證、日志記錄等操作;在工作流引擎中,可以使用責(zé)任鏈模式來(lái)實(shí)現(xiàn)任務(wù)的處理和流轉(zhuǎn);在事件驅(qū)動(dòng)系統(tǒng)中,可以使用責(zé)任鏈模式來(lái)處理事件的觸發(fā)和傳遞等等。

通過(guò)結(jié)合自定義注解和Spring的AOP功能,我們可以更加方便地應(yīng)用責(zé)任鏈模式,并在開(kāi)發(fā)過(guò)程中獲得更高的可擴(kuò)展性和靈活性。這種組件增強(qiáng)的方式使得責(zé)任鏈模式的實(shí)現(xiàn)更加簡(jiǎn)潔、可讀性更高,同時(shí)也提升了代碼的可維護(hù)性和可測(cè)試性。

總而言之,使用自定義注解和@Aspect實(shí)現(xiàn)責(zé)任鏈模式的組件增強(qiáng),是一種強(qiáng)大的編程技巧,能夠有效地將責(zé)任鏈的邏輯與業(yè)務(wù)組件解耦,提供了一種靈活且可擴(kuò)展的方式來(lái)處理請(qǐng)求和邏輯鏈的處理。這種結(jié)合注解和AOP的方式,使得責(zé)任鏈模式的應(yīng)用更加簡(jiǎn)單、優(yōu)雅,為我們的開(kāi)發(fā)工作帶來(lái)了便利和效益。

以上就是使用自定義注解和@Aspect實(shí)現(xiàn)責(zé)任鏈模式的組件增強(qiáng)的詳細(xì)代碼的詳細(xì)內(nèi)容,更多關(guān)于自定義注解和@Aspect實(shí)現(xiàn)組件增強(qiáng)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解SpringBoot如何統(tǒng)一后端返回格式

    詳解SpringBoot如何統(tǒng)一后端返回格式

    今天我們來(lái)聊一聊在基于SpringBoot前后端分離開(kāi)發(fā)模式下,如何友好的返回統(tǒng)一的標(biāo)準(zhǔn)格式以及如何優(yōu)雅的處理全局異常,感興趣的可以了解一下
    2021-07-07
  • Java中避免過(guò)多if-else的幾種方法

    Java中避免過(guò)多if-else的幾種方法

    這篇文章主要介紹了Java中避免過(guò)多if-else的幾種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • 談?wù)凧ava中整數(shù)類(lèi)型(short int long)的存儲(chǔ)方式

    談?wù)凧ava中整數(shù)類(lèi)型(short int long)的存儲(chǔ)方式

    在java中的整數(shù)類(lèi)型有四種,分別是byte short in long,本文重點(diǎn)給大家介紹java中的整數(shù)類(lèi)型(short int long),由于byte只是一個(gè)字節(jié)0或1,在此就不多說(shuō)了,對(duì)java中的整數(shù)類(lèi)型感興趣的朋友一起學(xué)習(xí)吧
    2015-11-11
  • Java中常用隊(duì)列的使用解讀

    Java中常用隊(duì)列的使用解讀

    這篇文章主要介紹了Java中常用隊(duì)列的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • Java代碼執(zhí)行順序——類(lèi)的初始化場(chǎng)景

    Java代碼執(zhí)行順序——類(lèi)的初始化場(chǎng)景

    這篇文章主要為大家介紹了Java代碼執(zhí)行順序類(lèi)的初始化場(chǎng)景實(shí)例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • JAVA不可變類(lèi)(immutable)機(jī)制與String的不可變性(推薦)

    JAVA不可變類(lèi)(immutable)機(jī)制與String的不可變性(推薦)

    這篇文章主要介紹了JAVA不可變類(lèi)(immutable)機(jī)制與String的不可變性(推薦)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-08-08
  • 詳解RabbitMQ中延遲隊(duì)列結(jié)合業(yè)務(wù)場(chǎng)景的使用

    詳解RabbitMQ中延遲隊(duì)列結(jié)合業(yè)務(wù)場(chǎng)景的使用

    這篇文章主要介紹了詳解RabbitMQ中延遲隊(duì)列結(jié)合業(yè)務(wù)場(chǎng)景的使用,延遲隊(duì)列中的元素都是帶有時(shí)間屬性的,延遲隊(duì)列就是用來(lái)存放需要在指定時(shí)間被處理的元素的隊(duì)列,需要的朋友可以參考下
    2023-05-05
  • java調(diào)用python代碼的兩種實(shí)現(xiàn)方式:Runtime.exec()和Jython

    java調(diào)用python代碼的兩種實(shí)現(xiàn)方式:Runtime.exec()和Jython

    在Java中調(diào)用Python代碼有多種方法,包括使用Runtime.exec()和第三方庫(kù)如Jython,Runtime.exec()通過(guò)系統(tǒng)命令執(zhí)行Python腳本,適用于簡(jiǎn)單的調(diào)用場(chǎng)景,Jython則是一個(gè)Python的Java實(shí)現(xiàn),允許在Java中直接運(yùn)行Python代碼,適用于更深層次的集成需求
    2025-01-01
  • 利用Spring?boot+LogBack+MDC實(shí)現(xiàn)鏈路追蹤

    利用Spring?boot+LogBack+MDC實(shí)現(xiàn)鏈路追蹤

    這篇文章主要介紹了利用Spring?boot+LogBack+MDC實(shí)現(xiàn)鏈路追蹤,MDC?可以看成是一個(gè)與當(dāng)前線程綁定的哈希表,可以往其中添加鍵值對(duì),下文詳細(xì)介紹需要的小伙伴可以參考一下
    2022-04-04
  • Spring cache整合redis代碼實(shí)例

    Spring cache整合redis代碼實(shí)例

    這篇文章主要介紹了Spring cache整合redis代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04

最新評(píng)論