场景 1:多租户 SaaS 平台的业务定制
业务挑战:
同一套代码服务多个租户
每个租户有独特的业务逻辑
需要动态上线租户定制功能
Lattice-Model 解决方案:
// 1. 定义通用能力 @Ability(code = "ORDER_ABILITY", name = "订单处理能力") public interface OrderAbility extends IAbility<OrderExt> { // 能力定义 } // 2. 定义扩展点 public interface OrderExt extends IBusinessExt { @Extension(code = "CALC_PRICE", reduceType = ReduceType.FIRST) BigDecimal calculatePrice(Order order); } // 3. 租户 A 的定制实现 @Business(code = "TENANT_A", name = "租户A") @Realization(codes = "TENANT_A") public class TenantAOrderExt implements OrderExt { @Override public BigDecimal calculatePrice(Order order) { // 租户 A 的定价逻辑:会员9折 return order.getOriginalPrice().multiply(new BigDecimal("0.9")); } } // 4. 租户 B 的定制实现 @Business(code = "TENANT_B", name = "租户B") @Realization(codes = "TENANT_B") public class TenantBOrderExt implements OrderExt { @Override public BigDecimal calculatePrice(Order order) { // 租户 B 的定价逻辑:满100减20 BigDecimal price = order.getOriginalPrice(); return price.compareTo(new BigDecimal("100")) >= 0 ? price.subtract(new BigDecimal("20")) : price; } } // 5. 业务调用(框架自动路由) @Service public class OrderService { @Autowired private OrderAbility orderAbility; public BigDecimal getOrderPrice(Order order) { // 根据 order.getBizCode() 自动调用对应租户的实现 return orderAbility.getDefaultRealization() .calculatePrice(order); } }
场景 2:电商平台的活动营销系统
业务挑战:
频繁的促销活动(双11、618、满减、折扣)
多个活动可能同时生效
活动规则复杂且变化快
Lattice-Model 解决方案:
// 1. 定义活动能力 @Ability(code = "PROMOTION_ABILITY", name = "促销活动能力") public interface PromotionAbility extends IAbility<PromotionExt> { // 能力定义 } // 2. 定义扩展点(支持多活动叠加) public interface PromotionExt extends IBusinessExt { @Extension( code = "APPLY_DISCOUNT", reduceType = ReduceType.ALL // 所有活动都执行 ) DiscountResult applyDiscount(OrderContext context); } // 3. 满减活动 @Product(code = "FULL_REDUCTION", name = "满减活动", priority = 100) public class FullReductionPromotion implements PromotionExt { @Override public DiscountResult applyDiscount(OrderContext context) { if (context.getTotalAmount().compareTo(new BigDecimal("200")) >= 0) { return DiscountResult.of(new BigDecimal("30"), "满200减30"); } return DiscountResult.empty(); } } // 4. 会员折扣 @Product(code = "VIP_DISCOUNT", name = "会员折扣", priority = 200) public class VipDiscountPromotion implements PromotionExt { @Override public DiscountResult applyDiscount(OrderContext context) { if (context.getUser().isVip()) { BigDecimal discount = context.getTotalAmount().multiply(new BigDecimal("0.05")); return DiscountResult.of(discount, "会员95折"); } return DiscountResult.empty(); } } // 5. 执行所有活动并聚合结果 @Service public class PromotionService { @Autowired private PromotionAbility promotionAbility; public List<DiscountResult> calculateDiscounts(OrderContext context) { // 使用自定义 Reducer 聚合所有活动结果 return promotionAbility.reduceExecute( ext -> ext.applyDiscount(context), new AllDiscountsReducer() // 收集所有优惠 ); } } // 6. 自定义聚合器 public class AllDiscountsReducer extends Reducer<DiscountResult, List<DiscountResult>> { @Override public List<DiscountResult> reduce(Collection<DiscountResult> elements) { return elements.stream() .filter(d -> d.getAmount().compareTo(BigDecimal.ZERO) > 0) .sorted(Comparator.comparing(DiscountResult::getPriority)) .collect(Collectors.toList()); } @Override public ReduceType reducerType() { return ReduceType.ALL; } }
场景 3:企业级 ERP 系统的行业定制
业务挑战:
同一套 ERP 服务多个行业(制造、零售、物流)
不同行业的业务流程差异大
需要支持行业特有功能
Lattice-Model 解决方案:
// 1. 定义通用的库存管理能力 @Ability(code = "INVENTORY_ABILITY", name = "库存管理能力") public interface InventoryAbility extends IAbility<InventoryExt> {} public interface InventoryExt extends IBusinessExt { // 扩展点1:库存扣减策略 @Extension(code = "DEDUCT_STOCK", reduceType = ReduceType.FIRST) DeductResult deductStock(Product product, int quantity); // 扩展点2:库存预警 @Extension(code = "STOCK_ALERT", reduceType = ReduceType.ALL) void checkStockAlert(Product product); } // 2. 制造业实现(考虑原材料库存) @UseCase( code = "MANUFACTURING_INVENTORY", name = "制造业库存管理", sdk = InventoryExt.class, priority = 100 ) @Realization(codes = "MANUFACTURING") public class ManufacturingInventoryExt implements InventoryExt { @Override public DeductResult deductStock(Product product, int quantity) { // 1. 检查成品库存 // 2. 如果不足,检查原材料是否可以生产 // 3. 触发生产计划 return deductWithProduction(product, quantity); } @Override public void checkStockAlert(Product product) { // 检查原材料库存预警 checkRawMaterialAlert(product); } } // 3. 零售业实现(考虑多仓库调拨) @UseCase( code = "RETAIL_INVENTORY", name = "零售业库存管理", sdk = InventoryExt.class, priority = 100 ) @Realization(codes = "RETAIL") public class RetailInventoryExt implements InventoryExt { @Override public DeductResult deductStock(Product product, int quantity) { // 1. 检查当前仓库库存 // 2. 如果不足,从其他仓库调拨 return deductWithTransfer(product, quantity); } @Override public void checkStockAlert(Product product) { // 检查全网库存分布 checkNetworkStockDistribution(product); } } // 4. 业务配置(支持动态切换) @Configuration public class BusinessConfiguration { @Bean public BusinessConfig manufacturingConfig() { return BusinessConfig.builder() .bizCode("MANUFACTURING") .products(Sets.newHashSet("MANUFACTURING_INVENTORY")) .build(); } @Bean public BusinessConfig retailConfig() { return BusinessConfig.builder() .bizCode("RETAIL") .products(Sets.newHashSet("RETAIL_INVENTORY")) .build(); } }
场景 4:微服务架构中的扩展点治理
技术挑战:
微服务拆分后扩展点分散
缺乏统一的扩展点管理
难以追踪扩展点的实现和调用
Lattice-Model 解决方案:
// 1. 在公共 API 模块定义扩展点 @Ability(code = "USER_SERVICE_ABILITY", name = "用户服务能力") public interface UserServiceAbility extends IAbility<UserServiceExt> {} public interface UserServiceExt extends IBusinessExt { @Extension( code = "USER_REGISTER", name = "用户注册", desc = "用户注册时的业务逻辑扩展点" ) RegisterResult register(RegisterRequest request); } // 2. 营销服务实现(发送优惠券) @Service @Realization(codes = "*", scenario = "MARKETING") public class MarketingUserExt implements UserServiceExt { @Override public RegisterResult register(RegisterRequest request) { // 新用户注册发送优惠券 sendWelcomeCoupon(request.getUserId()); return RegisterResult.success(); } } // 3. 风控服务实现(风险检测) @Service @Realization(codes = "*", scenario = "RISK_CONTROL") public class RiskControlUserExt implements UserServiceExt { @Override public RegisterResult register(RegisterRequest request) { // 注册时进行风险检测 if (detectRisk(request)) { return RegisterResult.fail("风险用户"); } return RegisterResult.success(); } } // 4. 用户服务编排多个扩展点 @Service public class UserService { @Autowired private UserServiceAbility ability; public void register(RegisterRequest request) { // 执行所有扩展点并验证结果 List<RegisterResult> results = ability.reduceExecute( ext -> ext.register(request), new AllResultsReducer() ); // 如果任何一个扩展点失败,则回滚 if (results.stream().anyMatch(r -> !r.isSuccess())) { rollbackRegistration(request); throw new BusinessException("注册失败"); } } }
最佳实践
3.1 注解使用规范
规范 1:Ability 定义规范
// ✅ 推荐:清晰的能力边界 @Ability( code = "ORDER_ABILITY", // 唯一标识,建议全大写+下划线 name = "订单处理能力", // 中文名称,便于理解 desc = "提供订单创建、支付、取消等核心能力", // 详细描述 parent = "TRADE_DOMAIN" // 所属领域(可选) ) public interface OrderAbility extends IAbility<OrderExt> { // 能力接口定义 } // ❌ 不推荐:职责不清晰 @Ability(code = "BUSINESS_ABILITY", name = "业务能力") public interface BusinessAbility extends IAbility<BusinessExt> { // 职责过于宽泛,难以维护 }
规范 2:Extension 定义规范
// ✅ 推荐:明确的扩展点语义 public interface OrderExt extends IBusinessExt { @Extension( code = "BEFORE_CREATE_ORDER", // 扩展点标识 name = "订单创建前置处理", desc = "在订单创建前执行的业务逻辑,如库存预占、优惠券核销", reduceType = ReduceType.ALL, // 所有实现都执行 protocolType = ProtocolType.LOCAL // 本地调用 ) void beforeCreateOrder(OrderContext context); @Extension( code = "CALC_ORDER_AMOUNT", // 金额计算 name = "计算订单金额", reduceType = ReduceType.FIRST // 只执行第一个匹配的 ) BigDecimal calculateAmount(Order order); } // ❌ 不推荐:缺少必要的元数据 public interface OrderExt extends IBusinessExt { @Extension // 缺少 code、reduceType 等关键信息 void process(Object data); }
规范 3:Business 和 Product 使用规范
// ✅ 推荐:Business 用于租户/业务线隔离 @Business( code = "TMALL", // 业务标识 name = "天猫", desc = "天猫业务线", priority = 1000 // 优先级(数值越小优先级越高) ) public class TmallBusiness implements IBusiness { // 天猫业务的全局配置 } // ✅ 推荐:Product 用于功能模块组合 @Product( code = "FLASH_SALE", // 产品标识 name = "限时秒杀", desc = "秒杀活动产品包", priority = 500 ) public class FlashSaleProduct implements IProduct { // 秒杀功能的配置 } // ✅ 推荐:UseCase 用于场景复用 @UseCase( code = "PRESALE_ORDER", // 用例标识 name = "预售订单场景", desc = "支持定金预售的订单处理流程", sdk = OrderExt.class, // 关联的扩展点接口 priority = 100 ) public class PresaleOrderUseCase implements IUseCase { // 预售场景的配置 }
3.2 扩展点实现规范
规范 4:Realization 实现规范
// ✅ 推荐:明确的业务绑定 @Service @Realization( codes = {"TMALL", "TAOBAO"}, // 支持多个业务 scenario = "DOUBLE_11" // 特定场景(可选) ) public class Double11OrderExt implements OrderExt { @Override public void beforeCreateOrder(OrderContext context) { // 双11 特殊逻辑:检查秒杀资格 checkFlashSaleEligibility(context); } @Override public BigDecimal calculateAmount(Order order) { // 双11 定价逻辑 return applyDouble11Discount(order); } } // ✅ 推荐:通配符支持默认实现 @Service @Realization(codes = "*") // 匹配所有业务 public class DefaultOrderExt implements OrderExt { @Override public void beforeCreateOrder(OrderContext context) { // 默认的前置检查 validateOrderBasicInfo(context); } @Override public BigDecimal calculateAmount(Order order) { // 默认定价逻辑 return order.getOriginalAmount(); } } // ❌ 不推荐:未指定 codes @Service public class SomeOrderExt implements OrderExt { // 缺少 @Realization 注解,无法被框架发现 }
规范 5:Reducer 使用规范
// ✅ 推荐:自定义 Reducer 处理复杂聚合逻辑 public class PriceMinReducer extends Reducer<BigDecimal, BigDecimal> { @Override public BigDecimal reduce(Collection<BigDecimal> elements) { // 返回最低价格 return elements.stream() .min(BigDecimal::compareTo) .orElse(BigDecimal.ZERO); } @Override public boolean willBreak(Collection<BigDecimal> elements) { // 如果有任何价格为 0,提前终止 return elements.stream() .anyMatch(p -> p.compareTo(BigDecimal.ZERO) == 0); } @Override public ReduceType reducerType() { return ReduceType.ALL; } } // 使用示例 @Service public class PriceService { @Autowired private PriceAbility priceAbility; public BigDecimal getBestPrice(Product product) { return priceAbility.reduceExecute( ext -> ext.calculatePrice(product), new PriceMinReducer() // 选择最低价 ); } }
规范 6:内置 ReduceType 使用场景
3.4 性能优化最佳实践
规范 7:使用 @ScanSkip 优化性能
// ✅ 推荐:跳过不需要扫描的方法 public interface OrderExt extends IBusinessExt { @Extension(code = "CALC_PRICE") BigDecimal calculatePrice(Order order); // 工具方法,不是扩展点 @ScanSkip default BigDecimal applyDiscount(BigDecimal price, BigDecimal rate) { return price.multiply(rate); } // 获取子扩展点(框架内部方法) @Override @ScanSkip IBusinessExt getBusinessExtByCode(String extCode, String scenario) { return IBusinessExt.super.getBusinessExtByCode(extCode, scenario); } }
规范 8:缓存策略
// ✅ 推荐:在 Ability 实现中缓存扩展实例 public class OrderAbilityImpl implements OrderAbility { // 缓存已创建的扩展实例 private final LoadingCache<String, OrderExt> extCache = CacheBuilder.newBuilder() .maximumSize(1000) .expireAfterWrite(10, TimeUnit.MINUTES) .build(new CacheLoader<String, OrderExt>() { @Override public OrderExt load(String bizCode) { return loadExtension(bizCode); } }); @Override public OrderExt getDefaultRealization() { String bizCode = getCurrentBizCode(); return extCache.getUnchecked(bizCode); } }
规范 9:扩展点单元测试
// ✅ 推荐:独立测试每个扩展实现 @RunWith(MockitoJUnitRunner.class) public class TmallOrderExtTest { @InjectMocks private TmallOrderExt tmallOrderExt; @Mock private DiscountService discountService; @Test public void testCalculateAmount_withVipDiscount() { // Given Order order = createTestOrder(new BigDecimal("100")); when(discountService.getVipRate()).thenReturn(new BigDecimal("0.9")); // When BigDecimal amount = tmallOrderExt.calculateAmount(order); // Then assertEquals(new BigDecimal("90.00"), amount); } @Test public void testBeforeCreateOrder_stockCheck() { // Given OrderContext context = createTestContext(); // When & Then assertDoesNotThrow(() -> tmallOrderExt.beforeCreateOrder(context)); verify(inventoryService, times(1)).checkStock(any()); } }
规范 10:集成测试框架集成
// ✅ 推荐:测试扩展点的自动发现和执行 @SpringBootTest @RunWith(SpringRunner.class) public class OrderAbilityIntegrationTest { @Autowired private OrderAbility orderAbility; @Test public void testExtensionAutoDiscovery() { // 验证扩展点是否被正确注册 OrderExt ext = orderAbility.getDefaultRealization(); assertNotNull(ext); // 验证扩展方法可以被调用 Order order = createTestOrder(); BigDecimal amount = ext.calculatePrice(order); assertTrue(amount.compareTo(BigDecimal.ZERO) > 0); } @Test public void testMultipleRealizationsExecution() { // 测试 ReduceType.ALL 是否执行所有实现 OrderContext context = createTestContext(); List<String> results = orderAbility.reduceExecute( ext -> { ext.beforeCreateOrder(context); return ext.getClass().getSimpleName(); }, new AllResultsReducer() ); // 验证所有实现都被执行 assertTrue(results.contains("TmallOrderExt")); assertTrue(results.contains("DefaultOrderExt")); } }
四、常见问题与解决方案
4.1 问题:扩展点未被发现
现象:实现了 IBusinessExt 但运行时找不到
排查步骤:
检查是否添加 @Realization 注解
检查 META-INF/services/IBusinessExt 是否生成
检查类加载器是否正确
解决方案:
// 确保注解处理器生效 <dependency> <groupId>com.google.auto.service</groupId> <artifactId>auto-service</artifactId> <scope>provided</scope> </dependency> // 确保 Realization 注解正确 @Service @Realization(codes = "YOUR_BIZ_CODE") public class YourExt implements YourBusinessExt { // 实现 }
4.2 问题:多个扩展点冲突
现象:同一个业务有多个扩展实现,不知道执行哪个
解决方案:使用优先级和场景隔离
// 方案 1:使用优先级 @Realization(codes = "TMALL") @Priority(100) // 数值越小优先级越高 public class HighPriorityExt implements OrderExt {} @Realization(codes = "TMALL") @Priority(500) public class LowPriorityExt implements OrderExt {} // 方案 2:使用场景隔离 @Realization(codes = "TMALL", scenario = "NORMAL") public class NormalOrderExt implements OrderExt {} @Realization(codes = "TMALL", scenario = "FLASH_SALE") public class FlashSaleOrderExt implements OrderExt {}
4.3 问题:类加载器泄漏
现象:插件卸载后内存未释放
解决方案:确保正确关闭 ClassLoader
// ✅ 使用 try-with-resources try (LatticeClassLoader classLoader = new LatticeClassLoader(urls, parent)) { // 使用 classLoader } // 自动关闭,释放资源 // ❌ 不推荐 LatticeClassLoader classLoader = new LatticeClassLoader(urls, parent); // 使用完未关闭,可能导致内存泄漏