Repository navigation
Module Features Infrastructure
基础设施类 Feature:rate-limit / idempotency / lock / cache / captcha / scheduling / storage / messaging / notification
本页回答:
coco-features/里 9 个基础设施类模块各自提供什么 SPI、默认实现、自动配置条件与配置属性。 依据:各模块pom.xml、src/main/java、META-INF实读,内容对应仓库main分支。这些模块的@since与官网文档标注的版本可能比最近发布的稳定版新,所在版本以 GitHub Releases 与 官网发布说明 为准,本页不断言发布版本。
| Feature id | 模块 | 在 starter 里? | Maven 依赖中的 Coco 模块 |
enabled 默认 |
运行期用 @ConditionalOnCocoFeature? |
包根 |
|---|---|---|---|---|---|---|
rate-limit |
coco-rate-limit |
否(构建期补加) |
coco-spring-boot-autoconfigure、coco-context、coco-exception、coco-i18n
|
false |
是 | io.github.coco.feature.ratelimit |
idempotency |
coco-idempotency |
否(构建期补加) |
coco-web、coco-i18n
|
false |
是 | io.github.coco.feature.idempotency |
lock |
coco-lock |
是 |
coco-exception、coco-i18n
|
false |
否 | io.github.coco.feature.lock |
cache |
coco-cache |
是 |
coco-exception、coco-i18n
|
false |
否 | io.github.coco.cache |
captcha |
coco-captcha |
是 |
coco-exception、coco-i18n
|
false |
否 | io.github.coco.captcha |
scheduling |
coco-scheduling |
是 |
coco-context、coco-i18n
|
true(matchIfMissing) |
否 | io.github.coco.scheduling |
storage |
coco-storage |
是 |
coco-exception、coco-i18n
|
false |
否 | io.github.coco.storage |
messaging |
coco-messaging |
是 |
coco-context、coco-i18n
|
true(matchIfMissing) |
否 | io.github.coco.messaging |
notification |
coco-notification |
是 |
coco-exception、coco-i18n
|
false |
否 | io.github.coco.notification |
读表要点:
-
包根不统一:
rate-limit、idempotency、lock在io.github.coco.feature.*下,其余六个在io.github.coco.<name>下。推荐哪种风格,设计意图未见文档说明,行为以各模块src/main/java的包路径为准;新增模块时与最近的同类模块保持一致,并在 PR 描述里说明(见 约定与规范)。 -
@ConditionalOnCocoFeature的缺失:只有 rate-limit 与 idempotency 在自动配置上使用它;其余 7 个靠各自的enabled属性开关。因此对这 7 个模块,coco.features.disabled在构建期影响依赖装配、裁剪与清单,运行期开关靠各自的coco.<name>.enabled。设计意图未见文档说明,行为以各模块自动配置类源码为准,详见 Feature 机制。 - 默认关闭的模块(
enabled=false)需要显式coco.<name>.enabled=true才会装配;scheduling与messaging默认开启。 - 只有 Servlet 应用才会注册 rate-limit 与 idempotency 的过滤器 / 拦截器。
lock、cache、captcha 各有三个自动配置:Coco<X>RedisAutoConfiguration(before 主配置,条件:enabled + store-type=<redis|two-level> + StringRedisTemplate 类存在)、Coco<X>RedisMissingDependencyAutoConfiguration(当 Redis 类缺失却选了 Redis 存储时 fail-fast)、主配置。rate-limit 与 idempotency 只有 Redis 配置 + 主配置(没有 MissingDependency 配置)。默认存储是进程内(IN_MEMORY / LOCAL),不适合多实例。
Redis 实现使用的 StringRedisTemplate:优先取 redis.template-bean-name 指定的 Bean(不存在或类型不对会抛 BeanCreationException);未指定时要求容器里只有一个 StringRedisTemplate,或只有一个 @Primary,否则启动失败。coco-web 的重放存储以及 rate-limit、idempotency、lock、cache、captcha 的 Redis 自动配置都带有签名一致的 resolve(...) 辅助方法,属性里也都有同名的 redis.template-bean-name。
条件注解里的 havingValue 是小写连字符字面量:in-memory、redis、two-level。这些模块的枚举(IN_MEMORY、REDIS、TWO_LEVEL)绑定宽松,但 @ConditionalOnProperty 不走枚举绑定:Spring Boot 的 OnPropertyCondition 用 equalsIgnoreCase 比较属性的原始字符串。结果是:
- 忽略大小写:
REDIS、Redis都能匹配redis;IN-MEMORY能匹配in-memory。 - 不会把下划线换成连字符:
IN_MEMORY、TWO_LEVEL这类枚举常量写法不会匹配in-memory、two-level,对应的条件 Bean 不会创建。 - 这些模块的源码里没有额外的归一化。
配置文件里请按小写连字符书写。
| 模块 | 资源包(src/main/resources) |
|---|---|
| rate-limit |
coco-rate-limit-messages(默认、_en_US、_zh_CN) |
| idempotency |
coco-idempotency-messages(默认、_zh_CN) |
| lock |
coco-lock-messages(默认、_zh_CN) |
| scheduling |
coco-scheduling-messages(默认、_zh_CN) |
| storage |
coco-storage-messages(默认、_zh_CN) |
| messaging |
coco-messaging-messages(默认、_en) |
| notification |
coco-notification-messages(默认、_en) |
| captcha |
coco-captcha-messages(默认、_en) |
| cache |
没有消息资源,自动配置里也没有 CocoMessageBundleRegistrar
|
资源包的语言后缀并不统一(
_zh_CN/_en_US/_en)。是否需要补齐,设计意图未见文档说明,行为以各模块src/main/resources为准。
坐标与路径:coco-features/coco-rate-limit。职责:可选的 Servlet 限流,key 与原子存储契约可替换(pom)。依赖另有 spring-webmvc、jackson-databind、jakarta.servlet-api;spotbugs-annotations(provided);Redis 为 optional。
触发方式:两条路径。① 过滤器 CocoRateLimitFilter:按 routes[].matcher 匹配请求;② MVC 拦截器 CocoRateLimitMvcInterceptor:处理方法 / 类上的 @CocoRateLimited("路由 id"),路由 id 必须在 routes 中声明,否则抛 IllegalStateException(@CocoRateLimited references an unknown route)。
| 类型 | 说明 |
|---|---|
CocoRateLimited(注解,@Target({TYPE, METHOD})) |
value() / route() 互为别名 |
CocoRateLimitKeyResolver(接口)/ DefaultCocoRateLimitKeyResolver
|
CocoRateLimitKey resolve(HttpServletRequest, CocoRateLimitRoute);默认实现只在 remote address 精确匹配 trusted-proxy.remote-addresses 时才解析 X-Forwarded-For
|
CocoRateLimitRouteMatcher(接口)/ DefaultCocoRateLimitRouteMatcher
|
按请求或路由 id 找路由 |
CocoRateLimitStore(接口)/ InMemoryCocoRateLimitStore / RedisCocoRateLimitStore
|
CocoRateLimitDecision acquire(CocoRateLimitPermit),原子判定 |
CocoRateLimitAlgorithm(枚举) |
FIXED_WINDOW、SLIDING_WINDOW、TOKEN_BUCKET
|
CocoRateLimitRoute |
配置路由:id、matcher(CocoRateLimitRequestMatchRule)、limit(默认 100)、window-seconds(默认 60)、algorithm(默认 FIXED_WINDOW) |
CocoRateLimitRequestHandler、CocoRateLimitResponseWriter、CocoRateLimitFilter、CocoRateLimitMvcInterceptor
|
具体类(final),其中 handler 与 writer 是带 @ConditionalOnMissingBean 的 Bean |
CocoRateLimitDecision、CocoRateLimitPermit、CocoRateLimitKey、CocoRateLimitStoreType(IN_MEMORY、REDIS)、CocoRateLimitErrorCode
|
模型与错误码 |
自动配置:CocoRateLimitRedisAutoConfiguration、CocoRateLimitAutoConfiguration(imports 中顺序如此)。主配置条件:@ConditionalOnCocoFeature(RATE_LIMIT) + coco.rate-limit.enabled=true(无 matchIfMissing)。Bean:cocoRateLimitMessageBundleRegistrar、cocoRateLimitClock(可替换)、CocoRateLimitKeyResolver、CocoRateLimitStore(store-type 缺省 in-memory,destroyMethod=close)、CocoRateLimitRouteMatcher(Servlet)、CocoRateLimitResponseWriter、CocoRateLimitRequestHandler、cocoRateLimitFilterRegistration、cocoRateLimitMvcConfigurer。
配置属性(coco.rate-limit):
| 键 | 默认值 |
|---|---|
enabled |
false |
store-type |
IN_MEMORY(另有 REDIS) |
routes |
空列表(元素字段见上) |
in-memory.max-entries |
10000 |
in-memory.cleanup-interval-seconds |
60 |
redis.key-prefix |
"coco:rate-limit:" |
redis.template-bean-name |
未设置 |
filter.excluded-path-patterns |
/actuator、/actuator/**、/health、/health/**
|
trusted-proxy.remote-addresses |
空(安全默认值:不读取任何转发头) |
依赖 / 测试:见总览;5 个 *Test。用户文档:rate-limit。
坐标与路径:coco-features/coco-idempotency。职责:可选的 Servlet 写请求幂等保护,租约存储可替换(pom)。依赖 coco-web(Feature 依赖也是 web)。
语义(module-layout.md):不缓存、不回放首次响应;仅正常完成的 2xx/3xx 保留租约到 TTL,异常以及所有 4xx/5xx 都释放租约,允许安全重试。
触发方式:CocoIdempotencyMvcInterceptor 只处理标注了 @CocoIdempotent(方法或类)的 HandlerMethod,且请求方法在 allowed-methods 中。获取租约失败时分别写出 DUPLICATE、UNAVAILABLE 或 INVALID_KEY 错误(CocoIdempotencyErrorCode)。拦截器顺序 HIGHEST_PRECEDENCE + 10(源码注释:限流先执行,幂等随后获得租约)。
| 类型 | 说明 |
|---|---|
CocoIdempotent(注解) |
namespace()(默认空)、ttlSeconds()(默认 -1,使用全局 TTL) |
CocoIdempotencyKeyResolver / DefaultCocoIdempotencyKeyResolver
|
CocoIdempotencyKey resolve(request, handlerMethod, intent);非法 key 抛 CocoIdempotencyKeyException
|
CocoIdempotencyOperationResolver / DefaultCocoIdempotencyOperationResolver
|
String resolve(request, handlerMethod),决定“同一个操作”的标识 |
CocoIdempotencyStore / InMemoryCocoIdempotencyStore / RedisCocoIdempotencyStore
|
AcquireResult acquire(CocoIdempotencyLease)、void release(CocoIdempotencyLease)
|
CocoIdempotencyResponseWriter / DefaultCocoIdempotencyResponseWriter
|
错误响应写出,默认复用 coco-web 的 CocoWebErrorResponseWriter
|
CocoIdempotencyLease(record)、CocoIdempotencyKey、CocoIdempotencyKeyException、CocoIdempotencyStoreType、CocoIdempotencyErrorCode
|
模型、枚举与错误码 |
自动配置:CocoIdempotencyRedisAutoConfiguration、CocoIdempotencyAutoConfiguration。主配置:@AutoConfigureBefore(CocoWebContextAutoConfiguration)、@ConditionalOnCocoFeature(IDEMPOTENCY)、coco.idempotency.enabled=true、Servlet。Bean:cocoIdempotencyMessageBundleRegistrar、cocoIdempotencyClock、CocoIdempotencyOperationResolver、CocoIdempotencyKeyResolver、CocoIdempotencyStore(缺省 in-memory)、CocoIdempotencyResponseWriter、cocoIdempotencySensitiveHeaderContributor(向 coco-web 登记 Idempotency-Key 头为敏感头)、cocoIdempotencyMvcConfigurer。
配置属性(coco.idempotency):
| 键 | 默认值 |
|---|---|
enabled |
false |
header-name |
"Idempotency-Key" |
ttl |
24h |
max-key-length |
128 |
max-entries |
100000 |
cleanup-interval |
1m |
store-type |
IN_MEMORY(另有 REDIS) |
allowed-methods |
POST、PUT、PATCH、DELETE
|
redis.key-prefix |
"coco:idempotency:" |
redis.template-bean-name |
未设置 |
测试:4 个 *Test。用户文档:idempotency。
坐标与路径:coco-features/coco-lock。职责:可选的方法级分布式锁,原子存储可替换(pom)。依赖 spring-aop、aspectjweaver、spring-expression。
| 类型 | 说明 |
|---|---|
CocoLock(注解) |
key()(必填表达式)、leaseMillis()、waitMillis()、pollIntervalMillis(),后三者默认 -1(使用全局默认) |
CocoLockAspect(MethodInterceptor)、CocoLockPointcut
|
对 @CocoLock 同步方法加锁,finally 里释放;由 cocoLockAdvisor(DefaultPointcutAdvisor)接入 AOP,顺序 aspect-order
|
CocoLockManager(接口)/ DefaultCocoLockManager
|
CocoLockResult tryAcquire(CocoLockRequest) |
CocoLockKeyResolver(接口)/ DefaultCocoLockKeyResolver
|
String resolve(String keyExpression, Object target, Method method, Object[] arguments) |
CocoLockStore(接口)/ InMemoryCocoLockStore / RedisCocoLockStore
|
acquire(lease)、renew(lease)、release(lease)
|
CocoLockHandle(AutoCloseable:lease()、reentrant()、lost())、CocoLockLease、CocoLockRequest、CocoLockResult、CocoLockStoreType、CocoLockErrorCode
|
模型与错误码 |
自动配置:CocoLockRedisAutoConfiguration、CocoLockRedisMissingDependencyAutoConfiguration、CocoLockAutoConfiguration。主配置条件仅 coco.lock.enabled=true。Bean:cocoLockMessageBundleRegistrar、cocoLockClock、CocoLockStore(缺省 in-memory)、CocoLockKeyResolver、CocoLockManager、CocoLockAspect、cocoLockAdvisor。
配置属性(coco.lock):
| 键 | 默认值 |
|---|---|
enabled |
false |
lease |
30s |
wait |
0 |
poll-interval |
50ms |
watchdog-enabled |
true |
watchdog-interval |
10s |
max-entries |
100000 |
cleanup-interval |
1m |
max-key-length |
256 |
aspect-order |
Ordered.LOWEST_PRECEDENCE - 100 |
store-type |
IN_MEMORY(另有 REDIS) |
redis.key-prefix |
"coco:lock:" |
redis.template-bean-name |
未设置 |
测试:4 个 *Test。用户文档:lock。
坐标与路径:coco-features/coco-cache。职责:两级缓存(Caffeine L1 + Redis L2),带 pub/sub 失效与穿透 / 击穿防护(pom)。依赖 spring-context-support、caffeine;Redis 为 optional。
| 类型 | 说明 |
|---|---|
CocoCacheManager(final,实现 Spring CacheManager) |
管理 CocoTwoLevelCache
|
CocoTwoLevelCache(final,继承 AbstractValueAdaptingCache) |
两级缓存实现 |
CocoCacheL2Store(接口)/ RedisCocoCacheL2Store
|
get(cacheName, key)、put(cacheName, key, value, ttlMillis)、evict(cacheName, key)、clear(cacheName);L2 扩展点
|
CocoCacheInvalidationPublisher(接口:publish(message)、sourceId())/ RedisCocoCacheInvalidationPublisher
|
失效广播扩展点 |
CocoCacheInvalidationListener、CocoCacheInvalidationMessage
|
失效消息的监听与载体 |
CocoCacheStoreType(枚举) |
LOCAL、TWO_LEVEL
|
自动配置:CocoCacheRedisAutoConfiguration、CocoCacheRedisMissingDependencyAutoConfiguration、CocoCacheAutoConfiguration。主配置:coco.cache.enabled=true + @EnableCaching;Bean CocoCacheManager,条件 @ConditionalOnMissingBean(CacheManager),即业务已有 CacheManager 时不会创建。Redis 配置在 store-type=two-level 时提供 cocoCacheL2RedisTemplate、CocoCacheL2Store、CocoCacheInvalidationPublisher、cocoCacheInvalidationContainer。
配置属性(coco.cache):
| 键 | 默认值 |
|---|---|
enabled |
false |
store-type |
LOCAL(两级缓存写作 two-level) |
maximum-size |
10000 |
expire-after-write |
10m |
cache-null-values |
true |
null-value-ttl |
30s |
redis.key-prefix |
"coco:cache:" |
redis.invalidation-channel |
"coco:cache:invalidation" |
redis.template-bean-name |
未设置 |
测试:2 个 *Test。用户文档:cache。
坐标与路径:coco-features/coco-captcha(@since 2.1.0)。职责:可替换的验证码 SPI(图形、滑块、短信验证码),带本地参考实现与可插拔答案存储(pom)。
| 类型 | 说明 |
|---|---|
CocoCaptchaService(final) |
对外入口:生成、校验验证码 |
CocoCaptchaGenerator(接口)/ ImageCocoCaptchaGenerator、SliderCocoCaptchaGenerator、SmsCodeCocoCaptchaGenerator
|
supportedType()、generate(captchaId)、matches(submitted, storedAnswer);自定义题型的扩展点
|
CocoCaptchaStore(接口)/ InMemoryCocoCaptchaStore / RedisCocoCaptchaStore
|
store(captchaId, answer, ttl)、consume(captchaId);答案存储扩展点
|
CocoCaptcha(record:captchaId、type、challenge、answer)、CocoCaptchaType(IMAGE、SLIDER、SMS_CODE)、CocoCaptchaStoreType(IN_MEMORY、REDIS) |
模型 |
自动配置:CocoCaptchaRedisAutoConfiguration、CocoCaptchaRedisMissingDependencyAutoConfiguration、CocoCaptchaAutoConfiguration。主配置条件 coco.captcha.enabled=true;Bean:cocoCaptchaMessageBundleRegistrar、CocoCaptchaStore、CocoCaptchaService。
配置属性(coco.captcha):enabled=false、ttl=2m、image-enabled=true、slider-enabled=true、sms-code-enabled=true、image-length=4、sms-code-length=6、slider-tolerance=5、store-type=IN_MEMORY、redis.key-prefix="coco:captcha:"、redis.template-bean-name(未设置)。
测试:3 个 *Test。用户文档:captcha。
坐标与路径:coco-features/coco-scheduling。职责:带注解支持的本地动态任务调度(pom)。依赖 spring-aop。
| 类型 | 说明 |
|---|---|
CocoScheduled(注解) |
name()、cron()、fixedDelay()、fixedRate()、zone()、initialDelay()(均为字符串,默认空)、enabled()(默认 true) |
CocoScheduledTaskRegistrar(SmartInitializingSingleton) |
扫描 Bean 上的 @CocoScheduled 并注册任务 |
CocoTaskRegistry(接口) |
register、replace、cancel(name)、list()、status(name):运行期动态管理 |
CocoTaskScheduler(接口,继承 CocoTaskRegistry 与 AutoCloseable)/ DefaultCocoTaskScheduler
|
调度器;可通过 @ConditionalOnMissingBean(CocoTaskScheduler) 替换 |
CocoTaskExecutionGuard(接口:tryAcquire(taskName)、release(taskName))/ InMemoryCocoTaskExecutionGuard
|
扩展点:多实例下做执行互斥(默认只在进程内) |
CocoTaskExecutionObserver(接口:onExecution(event))、CocoTaskExecutionEvent、CocoTaskExecutionOutcome(NONE、STARTED、SUCCEEDED、FAILED、SKIPPED) |
扩展点:观察执行结果 |
CocoTaskDefinition、CocoTaskDefinitionValidator、CocoTaskOverlapPolicy(ALLOW、SKIP)、CocoTaskScheduleType(CRON、FIXED_DELAY、FIXED_RATE)、CocoTaskStatus、CocoSchedulingException、CocoSchedulingMessage、CocoSchedulingMessageResolver
|
模型与异常 |
自动配置:io.github.coco.scheduling.CocoSchedulingAutoConfiguration,条件 coco.scheduling.enabled(matchIfMissing=true)。Bean:消息注册器、CocoSchedulingMessageResolver、CocoTaskDefinitionValidator、cocoTaskSchedulerExecutor(ThreadPoolTaskScheduler,@ConditionalOnMissingBean(TaskScheduler))、CocoTaskExecutionGuard、CocoTaskScheduler、CocoScheduledTaskRegistrar。
配置属性(coco.scheduling):enabled=true、pool-size=1、thread-name-prefix="coco-scheduling-"、shutdown.await-termination=30s、shutdown.interrupt=false。
测试:2 个 *Test(另有 1 个辅助 Java 文件)。用户文档:scheduling。
坐标与路径:coco-features/coco-storage。职责:可替换的对象存储 SPI,附带安全的本地参考实现(pom)。
| 类型 | 说明 |
|---|---|
CocoObjectStorage(接口) |
put(CocoObjectPutRequest)、open(key)、stat(key)、exists(key)、delete(key);存储扩展点
|
LocalCocoObjectStorage(storage.local,final) |
本地参考实现,根目录由 local.root 指定 |
ValidatingCocoObjectStorage |
在任意 CocoObjectStorage 外包一层内容校验 |
CocoStorageValidationBeanPostProcessor |
当 validation.enabled(缺省 true)时,把容器里每个 CocoObjectStorage Bean(含业务自己的实现)包成 ValidatingCocoObjectStorage
|
CocoContentValidator(接口:validate(CocoContentProbe))/ CocoSignatureContentValidator
|
内容校验扩展点,默认按文件签名(魔数)校验 |
CocoFileScanner(接口:scan(CocoContentProbe))/ NoOpCocoFileScanner
|
病毒 / 内容扫描扩展点,默认空操作 |
CocoObjectPutRequest、CocoObjectMetadata、CocoObjectResource、CocoContentProbe、CocoFileSignature、CocoFileSignatures、CocoStorageOverwritePolicy(REJECT、REPLACE)、CocoStorageException、CocoStorageErrorCode
|
模型与异常 |
自动配置:io.github.coco.storage.CocoStorageAutoConfiguration,条件 coco.storage.enabled=true。Bean:消息注册器、CocoObjectStorage(默认 LocalCocoObjectStorage)、CocoContentValidator、CocoFileScanner、静态方法 Bean CocoStorageValidationBeanPostProcessor。
配置属性(coco.storage):
| 键 | 默认值 |
|---|---|
enabled |
false |
overwrite-policy |
REJECT |
max-size-bytes |
10485760(10 MiB,DEFAULT_MAX_SIZE_BYTES) |
allowed-extensions |
jpg、jpeg、png、gif、webp、pdf、txt、csv
|
allowed-content-types |
空 |
local.root |
无(Path) |
local.orphan-grace-period |
5m |
local.gc-interval |
5m |
validation.enabled |
true |
validation.probe-size |
512 |
validation.reject-dangerous-signatures |
true |
validation.require-signature-match |
true |
测试:5 个 *Test。用户文档:storage。
坐标与路径:coco-features/coco-messaging。职责:进程内消息基础设施与传输 SPI(pom)。默认只做进程内投递,声明 CocoMessageTransport Bean 即可替换传输实现。
| 类型 | 说明 |
|---|---|
CocoMessagePublisher(接口) |
publish(CocoMessageEnvelope);默认方法 publish(topic, payload);默认实现 internal.DefaultCocoMessagePublisher
|
CocoMessageTransport(接口,AutoCloseable) |
publish(envelope)、subscribe(topic, handler)、close();默认实现 internal.LocalCocoMessageTransport;传输扩展点
|
CocoMessageHandler(接口) |
topic()、handle(envelope)
|
CocoMessageListener(注解) |
topic()、order()(默认 0),标在 Bean 方法上;由 internal.CocoMessageListenerRegistrar 注册 |
CocoMessageEnvelope、CocoMessageSubscription(AutoCloseable)、CocoMessagingException、support.CocoMessagingMessages
|
信封、订阅句柄与异常、消息文本辅助 |
| 策略枚举 |
CocoMessageDeliveryMode(SYNC、ASYNC)、CocoMessageFailurePolicy(FAIL_FAST、LOG_AND_CONTINUE)、CocoMessageNoSubscriberPolicy(IGNORE、FAIL)、CocoMessageAsyncShutdownPolicy(DRAIN、DISCARD) |
自动配置:io.github.coco.messaging.CocoMessagingAutoConfiguration,条件 coco.messaging.enabled(matchIfMissing=true)。Bean:消息注册器、CocoMessageTransport(destroyMethod=close)、CocoMessagePublisher、CocoMessageListenerRegistrar。
配置属性(coco.messaging):enabled=true、delivery-mode=SYNC、failure-policy=FAIL_FAST、no-subscriber-policy=IGNORE、async.queue-capacity=256、async.shutdown-await=30s、async.shutdown-policy=DRAIN。
测试:1 个 *Test。用户文档:messaging。
坐标与路径:coco-features/coco-notification(@since 2.1.0)。职责:可替换的通知通道 SPI(短信、邮件、站内信),带本地参考实现;云厂商 SDK 由应用自带(pom)。
| 类型 | 说明 |
|---|---|
CocoNotificationChannel(接口) |
supportedType()、send(CocoNotification);通道扩展点
|
CocoNotificationService(final) |
按通道类型路由发送 |
LoggingCocoNotificationChannel、InMemoryInAppCocoNotificationChannel
|
开发用参考通道(不真正发送 / 不跨实例、不持久化) |
CocoNotification(record:channelType、recipient、subject、content、attributes)、CocoNotificationResult(record:success、channelType、providerMessageId、detail)、CocoNotificationChannelType(SMS、EMAIL、IN_APP) |
模型 |
自动配置:io.github.coco.notification.CocoNotificationAutoConfiguration,条件 coco.notification.enabled=true。cocoNotificationService 先收集业务提供的 CocoNotificationChannel;某类型(SMS / EMAIL)没有业务通道且 logging-fallback=true 时补日志通道,IN_APP 没有业务通道且 in-memory-in-app=true 时补内存通道;每次补齐都会输出 WARN,提醒生产环境必须注册真实通道。
配置属性(coco.notification):enabled=false、logging-fallback=true、in-memory-in-app=true。
测试:2 个 *Test。用户文档:notification。官网另有汇总页 infra。
仓库 · CHANGELOG · CONTRIBUTING · GOVERNANCE · SECURITY · 许可证 Apache-2.0
本 Wiki 镜像自仓库的 docs/wiki 目录,请通过 PR 修改,不要在网页上直接编辑。
开始
架构
模块参考
约定与指南
速查与排障
仓库