如何在Apache Camel中配置Caffeine缓存(避免重复传参)
解决Apache Camel中Caffeine自定义缓存被默认覆盖的问题
当同时使用Spring Cache自动配置与Camel的Caffeine组件时,Spring会创建默认缓存实例,容易覆盖自定义配置。以下是针对性的解决步骤:
1. 手动注册自定义Caffeine缓存Bean
跳过Camel URI参数配置,直接用CaffeineCacheBuilder构建缓存实例并注册为Spring Bean,完全掌控缓存规则:
import com.github.benmanes.caffeine.cache.Caffeine; import org.springframework.cache.caffeine.CaffeineCache; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.beans.factory.annotation.Value; import java.util.concurrent.TimeUnit; @Configuration public class CustomCaffeineCacheConfig { @Value("${spring.cache.caffeine.maximumSize}") private long maximumSize; @Value("${spring.cache.caffeine.expireAfterWriteTime}") private long expireAfterWriteTime; @Value("${spring.cache.caffeine.cacheName}") private String cacheName; @Bean public CaffeineCache customTenantIdCache() { return new CaffeineCache( cacheName, Caffeine.newBuilder() .maximumSize(maximumSize) .expireAfterWrite(expireAfterWriteTime, TimeUnit.SECONDS) // 可根据实际时间单位调整 .build() ); } }
2. 在Camel路由中直接引用自定义缓存
修改路由逻辑,通过@Autowired注入自定义缓存Bean,在process()中直接操作缓存,避免依赖Camel组件自动创建的实例:
@Component public class TenantIdService extends ServiceBaseRouteBuilder { @Value("${platform.endpointsOrchestrated.tenantId}") private String msEndpoint; @Value("${spring.cache.caffeine.cacheName}") private String cacheName; private StmKafkaDTO stmKafkaDTORequest; @Autowired private CaffeineCache customTenantIdCache; @Override public void configure() { super.configure(); from(direct(ADD_TENANT_ID)) .unmarshal().json(StmKafkaDTO.class) .process(exchange -> { stmKafkaDTORequest = exchange.getIn().getBody(StmKafkaDTO.class); exchange.setProperty(STM_EVENT_EXCHANGE_PROPERTY, stmKafkaDTORequest.getPayload()); }) // 检查自定义缓存中是否存在数据 .process(exchange -> { String cacheKey = "TranslateEvent"; Object cachedValue = customTenantIdCache.get(cacheKey, key -> null); if (cachedValue != null) { exchange.getIn().setBody(cachedValue); exchange.setProperty("CACHE_HIT", true); } else { exchange.setProperty("CACHE_HIT", false); } }) .choice() .when(exchangeProperty("CACHE_HIT").isEqualTo(Boolean.FALSE)) .log(LoggingLevel.INFO, "Cache miss. Calling TranslateEvent...") // 缓存未命中时调用API .setHeader(Exchange.HTTP_METHOD, constant("GET")) .toD(msEndpoint + Util.BRIDGE_ENDPOINT + Util.THROW_EXCEPTION_OFF) .unmarshal().json(CoCountryMappingDTOResponse[].class) .process(TenantIdMapper::mapResponse) .process(PublishToPlatService::publishStmEventToPlatform) // 将结果存入自定义缓存 .process(exchange -> { String cacheKey = "TranslateEvent"; Object responseBody = exchange.getIn().getBody(); customTenantIdCache.put(cacheKey, responseBody); }) .otherwise() .log(LoggingLevel.INFO, "Cache hit. Response from cache: ${body}") .process(TenantIdMapper::mapResponse) .process(PublishToPlatService::publishStmEventToPlatform) .end() .stop(); } }
3. 禁用Spring Cache自动配置(可选)
如果Spring默认缓存配置仍带来干扰,可在启动类中禁用自动配置:
@SpringBootApplication(exclude = {CacheAutoConfiguration.class}) public class YourApplication { public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } }
核心说明
- 手动注册缓存Bean可以完全规避默认配置覆盖问题,精准控制缓存的过期、容量等规则
- 直接操作缓存实例的方式比Camel组件URI配置更灵活,便于复用缓存逻辑
- 若需多路由复用缓存操作,可将缓存查询、写入逻辑封装为独立的Processor类
内容的提问来源于stack exchange,提问作者Arianna Stefanoni
相关产品推荐
相关产品推荐

