欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

責(zé)任鏈模式

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

該模式的主要作用是:

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

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

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

應(yīng)用場景:

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

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

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

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

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

實(shí)踐案例

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

首先,我們需要定義一個(gè)自定義注解,用于標(biāo)識需要應(yīng)用責(zé)任鏈模式的方法或類??梢远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 {}

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

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ù)類型列表

        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)類

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) {
        // 處理請求
        System.out.println("FirstHandler handling request " + request);

        // 將請求傳遞給下一個(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) {
        // 處理請求
        System.out.println("SecondHandler handling request " + request);

        // 將請求傳遞給下一個(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) {
        // 處理請求
        System.out.println("ThirdHandler handling request " + request);
    }

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

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

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

Request類

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é)任鏈模式的方法或類。

啟動(dòng)類

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能夠識別和應(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!");
    }
}

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

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

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

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

總結(jié)

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

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

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

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

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

相關(guān)文章

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

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

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

    Java中避免過多if-else的幾種方法

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

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

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

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

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

    Java代碼執(zhí)行順序——類的初始化場景

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

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

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

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

    這篇文章主要介紹了詳解RabbitMQ中延遲隊(duì)列結(jié)合業(yè)務(wù)場景的使用,延遲隊(duì)列中的元素都是帶有時(shí)間屬性的,延遲隊(duì)列就是用來存放需要在指定時(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()和第三方庫如Jython,Runtime.exec()通過系統(tǒng)命令執(zhí)行Python腳本,適用于簡單的調(diào)用場景,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)前線程綁定的哈希表,可以往其中添加鍵值對,下文詳細(xì)介紹需要的小伙伴可以參考一下
    2022-04-04
  • Spring cache整合redis代碼實(shí)例

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

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

最新評論