1. 單例模式(結合 Spring @Component)
場景:配置中心、全局狀態管理
Spring 實現:
java
// 自動注冊為Spring Bean(默認單例)
@Component
public class AppConfig {@Value("${server.port}")private int port;// 其他配置屬性和方法
}// 使用方式(依賴注入)
@Service
public class UserService {@Autowiredprivate AppConfig appConfig;public void startServer() {System.out.println("啟動服務器,端口:" + appConfig.getPort());}
}
面試話術:
“在微服務項目中,我們用@Component
注解將配置類聲明為 Spring Bean,默認就是單例模式。比如 AppConfig 類統一管理應用配置,通過@Value
注入配置值,所有需要使用配置的服務直接@Autowired
即可。Spring 容器幫我們保證了全局唯一實例,無需手動實現雙重檢查鎖,代碼更簡潔。”
2. 工廠模式(結合 Spring FactoryBean)
場景:動態創建不同類型的數據源、Feign 客戶端
Spring 實現:
java
// 數據源工廠(簡化示例)
@Configuration
public class DataSourceConfig {@Beanpublic FactoryBean<DataSource> dataSourceFactory() {return new DynamicDataSourceFactory();}
}// 自定義FactoryBean
public class DynamicDataSourceFactory implements FactoryBean<DataSource> {@Overridepublic DataSource getObject() {// 根據條件創建不同數據源(如主從庫)return DataSourceBuilder.create().url("jdbc:mysql://localhost:3306/mydb").username("root").password("password").build();}@Overridepublic Class<?> getObjectType() {return DataSource.class;}
}// 使用方式
@Service
public class DataService {@Autowiredprivate DataSource dataSource;
}
面試話術:
“在分庫分表場景中,我們用FactoryBean
接口實現動態數據源創建。比如根據租戶 ID 選擇主庫或從庫,通過自定義DynamicDataSourceFactory
,Spring 會自動調用getObject()
方法獲取數據源實例。這種方式比傳統工廠模式更優雅,與 Spring 的依賴注入體系無縫集成。”
3. 策略模式(結合 @Autowired+Map)
場景:支付方式、限流策略選擇
Spring 實現:
java
// 支付策略接口
public interface PaymentStrategy {void pay(BigDecimal amount);
}// 支付寶策略
@Service("alipay")
public class AlipayStrategy implements PaymentStrategy {@Overridepublic void pay(BigDecimal amount) {System.out.println("支付寶支付:" + amount);}
}// 微信支付策略
@Service("wechatpay")
public class WechatPayStrategy implements PaymentStrategy {@Overridepublic void pay(BigDecimal amount) {System.out.println("微信支付:" + amount);}
}// 策略上下文(自動注入所有實現類)
@Service
public class PaymentService {@Autowiredprivate Map<String, PaymentStrategy> strategyMap;public void processPayment(String paymentType, BigDecimal amount) {PaymentStrategy strategy = strategyMap.get(paymentType);if (strategy != null) {strategy.pay(amount);} else {throw new IllegalArgumentException("不支持的支付類型");}}
}
面試話術:
“在支付模塊中,我們用策略模式結合 Spring 的自動注入特性。每種支付方式實現PaymentStrategy
接口并標記@Service
,通過@Autowired Map<String, PaymentStrategy>
可以自動收集所有策略實現類,Key 為 Bean 名稱(如alipay
)。這種方式避免了傳統策略模式中的大量if-else
,新增支付方式只需添加實現類,無需修改原有代碼。”
4. 觀察者模式(結合 Spring 事件機制)
場景:訂單狀態變更通知、異步事件處理
Spring 實現:
java
// 定義事件
public class OrderPaidEvent extends ApplicationEvent {private final String orderId;public OrderPaidEvent(Object source, String orderId) {super(source);this.orderId = orderId;}public String getOrderId() {return orderId;}
}// 發布事件
@Service
public class OrderService {@Autowiredprivate ApplicationEventPublisher eventPublisher;public void payOrder(String orderId) {// 處理支付邏輯eventPublisher.publishEvent(new OrderPaidEvent(this, orderId));}
}// 監聽事件(方式1:實現ApplicationListener)
@Component
public class SmsNotificationListener implements ApplicationListener<OrderPaidEvent> {@Overridepublic void onApplicationEvent(OrderPaidEvent event) {System.out.println("發送短信通知:訂單" + event.getOrderId() + "已支付");}
}// 監聽事件(方式2:@EventListener注解)
@Component
public class LoggingListener {@EventListenerpublic void handleOrderPaid(OrderPaidEvent event) {System.out.println("記錄日志:訂單" + event.getOrderId() + "已支付");}
}
面試話術:
“在訂單系統中,我們用 Spring 的事件機制替代傳統觀察者模式。當訂單支付成功后,通過ApplicationEventPublisher
發布OrderPaidEvent
,短信通知和日志記錄組件分別用@EventListener
注解監聽該事件。這種方式比手動維護觀察者列表更靈活,支持異步處理(通過@Async
注解),而且與 Spring 生態深度集成,例如可以結合事務實現事件的可靠發布。”
5. 裝飾器模式(結合 Spring AOP)
場景:權限校驗、日志增強、緩存切面
Spring 實現:
java
// 定義切面
@Aspect
@Component
public class LoggingAspect {@Around("execution(* com.example.service.*.*(..))")public Object logMethod(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("方法開始:" + joinPoint.getSignature().getName());long startTime = System.currentTimeMillis();Object result = joinPoint.proceed(); // 執行原方法long endTime = System.currentTimeMillis();System.out.println("方法結束:" + joinPoint.getSignature().getName() + ",耗時:" + (endTime - startTime) + "ms");return result;}
}
面試話術:
“在性能監控場景中,我們用 Spring AOP 實現裝飾器模式。通過@Around
注解定義切面,在方法執行前后添加日志記錄和耗時統計邏輯,無需修改原有業務代碼。這種方式比傳統繼承或組合更靈活,可以動態控制哪些方法需要增強,而且支持切入點表達式精確匹配目標方法。”
面試應答技巧
- 突出框架整合:強調如何利用 Spring 特性(如依賴注入、事件機制、AOP)簡化設計模式實現,而非手動編碼。
- 結合業務場景:舉例說明在微服務、分布式系統中的應用(如 Feign 客戶端工廠、Sentinel 限流策略)。
- 對比傳統方式:指出相比 “手搓” 設計模式,Spring 提供的方案更優雅、更符合開閉原則。
例如:
“在我們的微服務項目中,服務間通信使用 Feign 客戶端。當需要根據環境動態切換服務 URL 時,我們實現了
FeignClientFactoryBean
,利用 Spring 的工廠機制和配置中心(Nacos),根據不同環境加載不同的服務地址。這種方式比硬編碼 URL 更靈活,符合工廠模式的思想,同時充分利用了 Spring 的生態優勢。”