装饰器模式在Spring中的案例

设计模式-装饰器模式

装饰器模式所解决的问题是,在不改变原来方法代码的情况下对方法进行修饰,从而丰富方法功能。

Spring架构中的装饰器模式

在Spring架构中,以线程池进行举例。

线程池

线程池是一个对线程集中管理的对象,集中管理线程的创建和销毁以及调度。线程池中的线程所要执行的,就是传入线程池的任务,线程池安排线程对任务进行执行。

任务就是编码者想要交给线程池来执行的代码块,如果编码者想要给任务加上一些修饰,线程池便提供了修饰类入口。编码者可以在任务执行前后进行日志打印,线程变量设置或释放。

一般线程池配置

java 复制代码
import com.config.decorator.ThreadTaskDecorator;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@Configuration
public class ThreadPoolConfig {
	@Bean("taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(100);
        executor.setQueueCapacity(100);
        executor.setKeepAliveSeconds(60);
        executor.setTaskDecorator(new ThreadTaskDecorator());
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }
}

线程装饰器

类ThreadTaskDecorator实现了接口TaskDecorator的decorate方法,对原任务进行了装饰。

java 复制代码
import org.springframework.core.task.TaskDecorator;

public class ThreadTaskDecorator implements TaskDecorator {

    @Override
    public Runnable decorate(Runnable runnable) {

        return () -> {
            //前置
            try {
            //前置
                runnable.run();//原任务
            }finally {
                //后置
            }
            //后置
        };
    }
}

线程池初始化--装饰器模式体现

初始化代码来自类ThreadPoolTaskExecutor.class,对无关代码进行了折叠。

java 复制代码
protected ExecutorService initializeExecutor(ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {
        ...
        ThreadPoolExecutor executor = new ThreadPoolExecutor(this.corePoolSize, this.maxPoolSize, (long)this.keepAliveSeconds, TimeUnit.SECONDS, queue, threadFactory, rejectedExecutionHandler) {
            public void execute(Runnable command) {
                Runnable decorated = command;
                if (ThreadPoolTaskExecutor.this.taskDecorator != null) {
                    decorated = ThreadPoolTaskExecutor.this.taskDecorator.decorate(command);
                    if (decorated != command) {
                        ThreadPoolTaskExecutor.this.decoratedTaskMap.put(decorated, command);
                    }
                }

                super.execute(decorated);
            }

            .
            .
            .
        };
        
        .
        .
        .
        
        return executor;
    }

从初始化代码中可以看见,在创建executor时对ThreadPoolExecutor的父类接口Executor中的execute方法进行了实现,其中就是判断任务装饰器taskDecorator不为空的情况下,调用taskDecorator对象的decorate方法对command即原任务 进行装饰。这里的taskDecorator对象就是我们前面通过nre ThreadTaskDecorator()传递进去的,在线程池初始化的时候被调用到decorate,对原任务进行装饰。

复制代码
装饰器模式是将装饰和被装饰者进行分离,装饰和被装饰者相互独立。这种分离的方式使得,一种装饰只需要实现一次,便可以重复使用。这是代码复用的很好方案。

类图

超父类 :实现 超父类 :实现 实现 Executor execute(Runnable command) ThreadPoolTaskExecutor TaskDecorator taskDecorator initializeExecutor() ThreadPoolExecutor <<interface>> TaskDecorator Runnable decorate(Runnable command) ThreadTaskDecorator Runnable decorate(Runnable command) ThreadPoolConfig Executor taskExecutor()

相关推荐
大傻^26 分钟前
Spring AI Alibaba Agent开发:基于ChatClient的智能体构建模式
java·数据库·人工智能·后端·spring·springaialibaba
li星野30 分钟前
C++面试真题分享20260320
java·c++·面试
Irissgwe31 分钟前
c++特殊类设计
java·开发语言·c++
大傻^42 分钟前
Spring AI Alibaba 向量数据库集成:Milvus与Elasticsearch配置详解
数据库·人工智能·spring·elasticsearch·milvus·springai·springaialibaba
大傻^1 小时前
Spring AI Alibaba ChatClient实战:流式输出与多轮对话管理
java·人工智能·后端·spring·springai·springaialibaba
小帅学编程1 小时前
英语学习笔记
java·笔记·学习
学编程就要猛1 小时前
JavaEE初阶:文件操作和IO
java·java-ee
ba_pi1 小时前
每天写点什么2026-03-19-Doris三种存储模型
java·数据库·mysql
程序员老乔1 小时前
Java 新纪元 — JDK 25 + Spring Boot 4 全栈实战(二):Valhalla落地,值类型如何让电商DTO内存占用暴跌
java·spring boot·c#
SuniaWang1 小时前
《Spring AI + 大模型全栈实战》学习手册系列· 专题二:《Milvus 向量数据库:从零开始搭建 RAG 系统的核心组件》
java·人工智能·分布式·后端·spring·架构·typescript