【Lattice】最佳实践

简介: Lattice-Model 支持多租户SaaS、电商营销、ERP行业定制及微服务扩展,通过插件化实现业务隔离与动态加载,提升系统灵活性与可维护性。

场景 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 使用场景

image.png


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);
// 使用完未关闭,可能导致内存泄漏
目录
相关文章
|
4月前
|
Dubbo Java 测试技术
【Lattice】设计原理
Lattice 是一个轻量级业务扩展调用框架,通过模块化架构实现复杂业务定制的高效管理。支持动态发现、加载与执行扩展,提供清晰的分层设计,集成 Spring、Dubbo 等主流技术,助力企业应用灵活扩展。
478 0
|
4月前
|
运维 监控 供应链
Alibaba交易平台TMF2.0介绍
2017双11交易峰值达32.5万笔/秒,面对高并发与复杂业务需求,阿里推出TMF2.0框架,通过业务与平台分离、全链路可视化、配置化发布等创新,实现需求开发周期缩短至12天,支撑多业务快速试错与复用,构建可配置、可监控、可运维的电商技术新体系。
718 5
Alibaba交易平台TMF2.0介绍
Cron表达式每隔两小时执行一次
Cron表达式每隔两小时执行一次
836 1
|
4月前
|
消息中间件 安全 NoSQL
阿里云通过中国信通院首批安全可信中间件评估
近日,由中国信通院主办的 2025(第五届)数字化转型发展大会在京举行。会上,“阿里云应用服务器软件 AliEE”、“消息队列软件 RocketMQ”、“云数据库 Tair”三款产品成功通过中国信通院“安全可信中间件”系列评估,成为首批获此认证的中间件产品。此次评估覆盖安全可信要求、功能完备性、安全防护能力、性能表现、可靠性与可维护性等核心指标,标志着阿里云中间件产品在多架构适配与安全能力上达到行业领先水平。
538 232
|
4月前
|
设计模式 缓存 监控
如何在 Spring 项目中优雅地使用设计模式
本文深入探讨在Spring项目中如何优雅应用设计模式,结合依赖注入与IoC特性,通过工厂、策略、装饰者等模式提升代码可维护性与扩展性,助力构建高效、灵活的Java应用。
332 5
|
2月前
|
数据采集 人工智能 Java
核心目标:构建Java全流程AI Agent
在AI深度赋能企业背景下,依托JBoltAI框架,打造贯穿业务全链路的全流程AI Agent。突破传统自动化局限,实现跨模块协同、多系统融合与自适应迭代,推动Java生态智能化升级。
384 5
|
4月前
|
设计模式 Java
【TMF】源码分析 1.0 LatticeClassLoader
LatticeClassLoader扩展Java双亲委派模型,支持多自定义类加载器的委托加载。类加载失败后依次尝试自定义加载器,实现插件化容错;资源获取优先父加载器,支持单资源查找与多资源聚合,适用于插件系统、多租户隔离及SPI扩展,保障业务隔离与灵活扩展。
195 1
|
4月前
|
存储 消息中间件 关系型数据库
从 Snowflake 到 Apache Doris:Planet 实时分析成本直降 80%、查询加速 90 倍
Planet深耕支付与税务数字化近40年,服务全球零售、酒店与旅游行业。为应对数据增长挑战,其数据团队将数仓从Snowflake迁移至Apache Doris,实现月成本降低80%、查询性能提升最高90倍,并达成实时分析能力,构建了高效、低成本、可扩展的数据新架构,为业务发展奠定坚实基础。
202 0
从 Snowflake 到 Apache Doris:Planet 实时分析成本直降 80%、查询加速 90 倍
|
4月前
|
存储 Java 编译器
【TMF】 解析器底层原理分析
该注解处理器在编译期自动扫描特定注解(如@Extension、@Business),收集标记的类或方法,生成SPI配置文件,实现服务接口与实现类的自动注册,提升开发效率与准确性。
195 2