SpringBoot中暗藏的设计模式

想获取更多高质量的Java技术文章?欢迎访问 Java技术小馆官网,持续更新优质内容,助力技术成长!

一、工厂模式

想象一下你去奶茶店点单------你只需要告诉店员要"珍珠奶茶",后厨就会自动完成煮茶、加料、封口整套流程。这就是工厂模式在SpringBoot中的体现。

典型应用场景:

  1. Bean的创建过程(ApplicationContext就是超级工厂)
  2. 第三方库的集成(如RedisTemplate的生成)
  3. 条件化配置(@Conditional系列注解)
less 复制代码
// 自定义奶茶工厂
@Configuration
public class MilkTeaFactory {
    
    @Bean
    @Scope("prototype")
    public MilkTea pearlMilkTea() {
        MilkTea tea = new MilkTea();
        tea.addIngredient("珍珠");
        tea.setSugarLevel(50);
        return tea;
    }
}

当你在Controller中@Autowired一个MilkTea对象时,SpringBoot就像奶茶店后厨一样,按配方为你制作好对象。这就是为什么我们几乎不需要自己new对象的原因。

二、单例模式

公司里的CEO只能有一个,这就是单例模式的精髓。SpringBoot通过这个模式管理着最重要的核心组件。

实现方式对比表

方式 优点 典型应用
@Bean注解 配置灵活 数据源配置
@Component注解 自动扫描 Service层组件
枚举实现 防反射攻击 全局状态管理
less 复制代码
@Service // 这个注解让UserService成为单例
public class UserService {
    // 业务方法...
}

// 测试验证
@Test
void testSingleton() {
    UserService instance1 = context.getBean(UserService.class);
    UserService instance2 = context.getBean(UserService.class);
    assertSame(instance1, instance2); // 确认是同一个实例
}

单例模式节省了内存开销,但也需要注意线程安全问题。Spring通过Bean的作用域设计(@Scope)让开发者可以灵活控制。

三、模板方法模式

做红烧肉和糖醋排骨的步骤都是:准备食材→焯水→炒制→收汁。这就是模板方法模式------定义算法骨架,允许子类重写特定步骤。

Spring中的经典实现

  1. JdbcTemplate的execute方法
  2. RestTemplate的请求处理流程
  3. @Transactional的事务管理
csharp 复制代码
public abstract class CookingTemplate {
    // 模板方法(final防止被重写)
    public final void cook() {
        prepareIngredients();
        blanching();
        stirFry();
        thickenSauce();
    }
    
    // 抽象方法(必须由子类实现)
    protected abstract void prepareIngredients();
    
    // 默认实现(可选重写)
    protected void blanching() {
        System.out.println("焯水30秒");
    }
    
    // 其他步骤...
}

// 具体实现
@Component
public class BraisedPork extends CookingTemplate {
    @Override
    protected void prepareIngredients() {
        System.out.println("准备五花肉500g");
    }
}

下次使用JdbcTemplate时,你会注意到它已经帮你处理了连接获取、异常处理等通用逻辑,你只需要关注SQL执行本身。

四、代理模式

明星都有经纪人处理日常事务,这个经纪人就是代理对象。Spring AOP的核心机制正是基于动态代理。

代理类型对比

代理类型 实现方式 特点
JDK动态代理 接口代理 性能较好
CGLIB代理 类继承 无需接口
typescript 复制代码
// 业务接口
public interface UserService {
    void register(User user);
}

// 目标类
@Service
public class UserServiceImpl implements UserService {
    @Override
    @Transactional // 事务代理的典型应用
    public void register(User user) {
        // 注册逻辑
    }
}

// 自动生成的代理类(伪代码)
public class UserServiceProxy implements UserService {
    private UserService target;
    
    public void register(User user) {
        startTransaction();
        try {
            target.register(user);
            commitTransaction();
        } catch (Exception e) {
            rollbackTransaction();
        }
    }
}

当你在方法上添加@Transactional注解时,Spring就会悄悄创建一个代理对象来管理事务。这就是为什么添加注解就能实现事务控制的原因。

五、观察者模式

就像微信订阅号,当博主发文时,所有粉丝都会收到通知。Spring的事件机制完美诠释了这一模式。

核心组件

  1. ApplicationEvent(事件)
  2. ApplicationListener(监听器)
  3. ApplicationEventPublisher(发布者)
typescript 复制代码
// 自定义订单事件
public class OrderEvent extends ApplicationEvent {
    private String orderId;
    
    public OrderEvent(Object source, String orderId) {
        super(source);
        this.orderId = orderId;
    }
    // getter...
}

// 短信通知监听器
@Component
public class SmsListener implements ApplicationListener<OrderEvent> {
    @Override
    public void onApplicationEvent(OrderEvent event) {
        sendSms(event.getOrderId());
    }
}

// 使用示例
@Service
public class OrderService {
    @Autowired
    private ApplicationEventPublisher publisher;
    
    public void createOrder(Order order) {
        // 创建订单逻辑
        publisher.publishEvent(new OrderEvent(this, order.getId()));
    }
}

这种解耦设计让系统扩展变得容易。当需要新增邮件通知时,只需添加新的监听器即可,无需修改订单创建逻辑。

六、适配器模式

出国旅行时用到的电源转换插头就是适配器的现实版。Spring MVC中的HandlerAdapter就是这个模式的经典应用。

适配场景

  1. 控制器方法参数解析
  2. 返回值处理
  3. 跨版本接口兼容
java 复制代码
// 旧版支付接口
public class LegacyPayment {
    public String pay(int amount) {
        return "现金支付:" + amount + "元";
    }
}

// 适配器
@Component
public class PaymentAdapter implements ModernPayment {
    
    private final LegacyPayment legacyPayment;
    
    public PaymentAdapter(LegacyPayment legacyPayment) {
        this.legacyPayment = legacyPayment;
    }
    
    @Override
    public String onlinePay(int amount) {
        String result = legacyPayment.pay(amount);
        return "适配后的结果:" + result;
    }
}

// 现代支付接口
public interface ModernPayment {
    String onlinePay(int amount);
}

// 控制器使用
@RestController
public class PaymentController {
    @Autowired
    private ModernPayment payment;
    
    @PostMapping("/pay")
    public String handlePay(@RequestParam int amount) {
        return payment.onlinePay(amount);
    }
}

当HandlerAdapter处理不同类型的Controller时(如@Controller与HttpRequestHandler),正是通过适配器模式实现了统一调用。

设计模式认知的三个阶段

  1. 看山是山:在SpringBoot中看到各种注解和配置
  2. 看山不是山:发现背后隐藏的设计模式
  3. 看山还是山:理解模式组合带来的架构之美

SpringBoot就像精心设计的乐高套装,设计模式就是那些标准接口的积木块。当我们理解这些模式后,就能:

  • 更高效地使用框架特性
  • 编写更优雅的代码
  • 快速定位疑难问题
  • 设计出可扩展的系统架构

最后送大家一个调试技巧:在IDEA中打开"Show Spring Beans"视图(Ctrl+Alt+Shift+U),你会看到单例池中所有Bean的庐山真面目。试着找出本文提到的各个模式实现,这将是你进阶Spring高手的重要一步!

想获取更多高质量的Java技术文章?欢迎访问 Java技术小馆官网,持续更新优质内容,助力技术成长!

相关推荐
24k小善1 小时前
Flink TaskManager详解
java·大数据·flink·云计算
想不明白的过度思考者1 小时前
Java从入门到“放弃”(精通)之旅——JavaSE终篇(异常)
java·开发语言
天天扭码1 小时前
总所周知,JavaScript中有很多函数定义方式,如何“因地制宜”?(ˉ﹃ˉ)
前端·javascript·面试
.生产的驴1 小时前
SpringBoot 封装统一API返回格式对象 标准化开发 请求封装 统一格式处理
java·数据库·spring boot·后端·spring·eclipse·maven
Pasregret1 小时前
多级缓存架构深度解析:从设计原理到生产实践
缓存·架构
国科安芯1 小时前
面向高性能运动控制的MCU:架构创新、算法优化与应用分析
单片机·嵌入式硬件·安全·架构·机器人·汽车·risc-v
猿周LV1 小时前
JMeter 安装及使用 [软件测试工具]
java·测试工具·jmeter·单元测试·压力测试
晨集1 小时前
Uni-App 多端电子合同开源项目介绍
java·spring boot·uni-app·电子合同
时间之城1 小时前
笔记:记一次使用EasyExcel重写convertToExcelData方法无法读取@ExcelDictFormat注解的问题(已解决)
java·spring boot·笔记·spring·excel
椰羊~王小美2 小时前
LeetCode -- Flora -- edit 2025-04-25
java·开发语言