1. 策略模式 ⭐⭐⭐⭐⭐
消灭 if-else 的核心武器,基于 Spring 容器自动选择策略。
步骤:
定义策略接口
public interface Strategy { String getType(); void execute(); }实现多个策略并用
@Component注册@Component public class StrategyA implements Strategy { @Override public String getType() { return "A"; } @Override public void execute() { /* ... */ } } @Component public class StrategyB implements Strategy { @Override public String getType() { return "B"; } @Override public void execute() { /* ... */ } }创建策略选择器
@Component public class StrategySelector { private final Map<String, Strategy> strategyMap = new HashMap<>(); // 4. Spring自动注入所有Strategy实现到Map(详见文档末尾“注入条件”) public StrategySelector(Map<String, Strategy> strategyMap) { // 遍历注入的Map,按业务key重组 strategyMap.values().forEach(s -> this.strategyMap.put(s.getType(), s)); } // 5. 选择策略 public Strategy getStrategy(String type) { Strategy strategy = strategyMap.get(type); if (strategy == null) { throw new IllegalArgumentException("No strategy for: " + type); } return strategy; } }
2. 工厂模式 ⭐⭐⭐⭐⭐
创建对象的“万能工厂”,通过 Spring 容器自动装配产品族。
步骤:
定义产品接口
public interface Product { String getType(); void doSomething(); }多个产品实现并注册
@Component public class ProductA implements Product { @Override public String getType() { return "A"; } @Override public void doSomething() { /*...*/ } } @Component public class ProductB implements Product { @Override public String getType() { return "B"; } @Override public void doSomething() { /*...*/ } }创建工厂类(Spring自动注入所有产品)
@Component public class ProductFactory { private final Map<String, Product> productMap; // 构造器注入:Spring会将所有Product的实现注入到Map中(key=bean名称,默认类名首字母小写) public ProductFactory(Map<String, Product> productMap) { this.productMap = productMap; } public Product create(String type) { Product product = productMap.get(type); // 或自定义getType()映射 if (product == null) throw new IllegalArgumentException("Unknown product type"); return product; } }与策略模式的区别:工厂侧重于创建/获取对象,策略侧重行为互换,但 Spring 集成写法相似。
3. 责任链模式 ⭐⭐⭐⭐⭐
多个处理器依次尝试,直到有人处理。
步骤:
定义请求上下文
public class RequestContext { private boolean approved = false; private String rejectReason; private String approvedBy; // getters & setters... }编写 Handler 接口
public interface Handler { boolean handle(RequestContext context); // true=处理完毕,不再传递 }具体处理器(
@Component+@Order控制顺序)@Component @Order(1) public class ManagerHandler implements Handler { public boolean handle(RequestContext context) { // 逻辑:通过则设置approved=true,返回true;否则返回false return true; } } @Component @Order(2) public class DirectorHandler implements Handler { /* ... */ }组装责任链(
@PostConstruct确保只排序一次)@Component public class HandlerChain { private final List<Handler> handlers; public HandlerChain(List<Handler> handlers) { this.handlers = handlers; } @PostConstruct public void init() { AnnotationAwareOrderComparator.sort(handlers); } public void process(RequestContext context) { for (Handler handler : handlers) { if (handler.handle(context)) break; } } }使用
@Autowired HandlerChain chain; // ... RequestContext ctx = new RequestContext(); chain.process(ctx);
4. 模板方法模式 ⭐⭐⭐⭐⭐
父类定义骨架,子类填写细节。
步骤:
抽象模板类
public abstract class AbstractExportService { public final void export() { prepareData(); writeFile(); cleanUp(); } protected abstract void prepareData(); protected abstract void writeFile(); protected void cleanUp() { /* 钩子:默认空实现 */ } }具体子类
@Component public class ExcelExportService extends AbstractExportService { @Override protected void prepareData() { /*...*/ } @Override protected void writeFile() { /*...*/ } }Controller中使用(注入所有子类)
@RestController public class ExportController { private final Map<String, AbstractExportService> exportServiceMap; // 注入时 key 为 bean 名称(类名首字母小写,或用@Service("excel")指定) public ExportController(Map<String, AbstractExportService> exportServiceMap) { this.exportServiceMap = exportServiceMap; } @GetMapping("/export/{type}") public void doExport(@PathVariable String type) { exportServiceMap.get(type).export(); } }
5. 代理模式 ⭐⭐⭐⭐⭐
控制对象访问,增强功能(Spring AOP 的基础)。
Spring 推荐方式:
- 声明式:
@Transactional、@Cacheable等本质是动态代理。 手动示例:统计方法耗时。
@Component public class SimpleService implements IService { @Override public void work() { /* ... */ } } @Component public class ServiceProxy implements IService { private final IService target; public ServiceProxy(@Qualifier("simpleService") IService target) { this.target = target; } @Override public void work() { long start = System.currentTimeMillis(); target.work(); System.out.println("cost: " + (System.currentTimeMillis() - start)); } }更常用的是直接使用 Spring AOP(
@Aspect+@Around)实现动态代理。
6. 状态模式 ⭐⭐⭐⭐⭐
将状态逻辑拆分为独立的状态对象,避免大量 if-else。
步骤(订单状态机):
状态接口
public interface OrderState { void pay(OrderContext ctx); void ship(OrderContext ctx); }具体状态
@Component public class PendingPaymentState implements OrderState { public void pay(OrderContext ctx) { // 支付成功后切换状态 ctx.setState(ctx.getPaidState()); } public void ship(OrderContext ctx) { throw new UnsupportedOperationException(); } } // PaidState, ShippedState... 同理上下文持有状态
@Component public class OrderContext { private OrderState current; // 注入所有状态 @Autowired private PendingPaymentState pendingPaymentState; @Autowired private PaidState paidState; //... getters/setters,初始化为 pendingPaymentState }Spring 中可使用状态枚举配合
Map<OrderStatus, OrderState>自动注入。
7. 观察者模式 ⭐⭐⭐⭐
一对多通知,Spring 事件机制天然支持。
步骤:
定义事件
public class OrderCreatedEvent extends ApplicationEvent { private final Long orderId; public OrderCreatedEvent(Object source, Long orderId) { super(source); this.orderId = orderId; } // getter }发布事件
@Component public class OrderService { @Autowired private ApplicationEventPublisher publisher; public void createOrder() { // 业务... publisher.publishEvent(new OrderCreatedEvent(this, orderId)); } }监听事件(可使用
@EventListener或@TransactionalEventListener)@Component public class SendSmsListener { @EventListener public void handleOrderCreated(OrderCreatedEvent event) { // 发短信 } }
8. 门面模式 ⭐⭐⭐⭐
为复杂子系统提供统一入口,Service 层常见模式。
示例: 下单门面聚合库存、支付、物流三个服务。
@Component
public class OrderFacade {
@Autowired private InventoryService inventoryService;
@Autowired private PaymentService paymentService;
@Autowired private LogisticsService logisticsService;
public void placeOrder(OrderDTO dto) {
inventoryService.reduceStock(dto.getSku());
paymentService.charge(dto.getAmount());
logisticsService.scheduleDelivery(dto.getOrderId());
}
}9. 装饰器模式 ⭐⭐⭐⭐
动态附加责任,比继承更灵活。
示例: 对数据读写组件增加缓存装饰器。
public interface DataService { String read(); }
@Component("basicDataService")
public class BasicDataService implements DataService { /*...*/ }
@Component
public class CacheDecorator implements DataService {
private final DataService delegate;
public CacheDecorator(@Qualifier("basicDataService") DataService delegate) {
this.delegate = delegate;
}
@Override
public String read() {
// 先查缓存,没有则调用delegate并缓存
return delegate.read();
}
}10. 适配器模式 ⭐⭐⭐⭐
兼容两个不匹配的接口,常用于整合外部系统。
// 目标接口
public interface Logger { void log(String msg); }
// 被适配的第三方类
public class ExternalLogLib { public void writeLog(String text) { /*...*/ } }
// 适配器
@Component
public class ExternalLogAdapter implements Logger {
@Autowired private ExternalLogLib externalLogLib;
@Override
public void log(String msg) {
externalLogLib.writeLog(msg);
}
}11. DDD(领域驱动设计) ⭐⭐⭐⭐⭐⭐
聚焦核心业务复杂度,分层架构与战略设计。
核心步骤(简化分层):
- 用户接口层:Controller,接收请求并调用应用服务。
- 应用层:
@Service应用服务,编排领域对象,不包含业务逻辑。 - 领域层:实体(Entity)、值对象(Value Object)、聚合根(Aggregate Root)、领域服务(Domain Service)、仓储接口(Repository Interface)。
- 基础设施层:仓储实现(
@Repository),将聚合持久化到数据库。
关键原则:
- 领域层无任何 Spring 注解,纯 POJO。
- 通过构造器注入将仓储接口注入领域服务或应用服务。
- 聚合内通过根实体确保一致性。
12. Event Driven(事件驱动架构) ⭐⭐⭐⭐⭐⭐
通过事件解耦服务,提升伸缩性和最终一致性。
Spring 实现:
- 本地事件:
ApplicationEventPublisher+@EventListener(见观察者模式)。 分布式事件:集成 Kafka / RabbitMQ。
// 发布领域事件到消息队列 @Autowired private KafkaTemplate<String, DomainEvent> kafkaTemplate; public void publish(DomainEvent event) { kafkaTemplate.send("topic-name", event); } // 消费 @KafkaListener(topics = "topic-name") public void handle(DomainEvent event) { /*...*/ }推荐配合
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)保证事务提交后再发消息。
13. Saga ⭐⭐⭐⭐⭐⭐
分布式事务的最终一致性方案,通过协调正向/补偿操作。
编排型 Saga(借助事件驱动):
- 每个微服务监听前序事件,执行本地事务并发布新事件。
若失败,发布补偿事件,上游监听并回滚。
// 服务A发布订单创建事件,服务B监听并扣库存 // 若扣库存失败,服务B发布库存不足事件,服务A监听后进行补偿(取消订单)实现时可配合 Spring Cloud Stream / Axon Framework。
14. CQRS(命令查询职责分离) ⭐⭐⭐⭐⭐⭐
读写模型分离,最大化性能与扩展性。
简单实现:
- 命令侧:应用服务接收 Command,调用领域逻辑,写入主库。
查询侧:
@Service直接从读库或缓存查询 DTO。// 命令 @PostMapping public void createOrder(@RequestBody CreateOrderCmd cmd) { commandService.handle(cmd); } // 查询(独立Controller或同一模块内分离) @GetMapping("/orders/{id}") public OrderView queryOrder(@PathVariable Long id) { return queryService.findById(id); }高级玩法:事件溯源,将所有状态变更存储为事件流,查询视图由事件投影构建。
SpringBoot 2.7 注入条件(集合/Map注入)
核心行为: Spring 会自动将所有实现了某个接口或父类的 Bean 注入到 List 或 Map 中。
- 注入 List:
@Autowired List<SomeInterface> list;
会按Order排序包含所有实现类的 Bean。 - 注入 Map:
@Autowired Map<String, SomeInterface> map;
key 为 Bean 的名称(默认类名首字母小写,若用@Service("myName")则用指定名称),value 为实例。 - 没有实现类时: Spring 默认会注入一个空集合(EmptyList/EmptyMap),不会报错。若希望强制存在才注入,可使用
@Autowired(required = true),但注入集合时required=true仍允许空集合,除非你将它用在非集合字段上。 推荐方式: 构造器注入,显式声明 final 字段,避免
@Autowired注解(Spring 4.3+ 单构造器自动注入)。@Component public class StrategySelector { private final Map<String, Strategy> strategyMap = new HashMap<>(); // 构造器注入:Spring 自动将所有的 Strategy 实现类注入 Map public StrategySelector(Map<String, Strategy> allStrategies) { allStrategies.values().forEach(s -> strategyMap.put(s.getType(), s)); } }
在 Spring Boot 2.7 (Spring Framework 5.3.x) 下此行为完全稳定,完美支持策略/工厂等模式的自动装配。
评论