Design and Implementation of a Generic Asynchronous Processing SDK for Spring Applications

This article introduces a generic asynchronous processing SDK for Spring-based backend systems, explaining its purpose, advantages, underlying principles, components such as Kafka, XXL‑Job, MySQL, and Vue, design patterns employed, database schema, configuration via Apollo, usage examples, and deployment details.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Design and Implementation of a Generic Asynchronous Processing SDK for Spring Applications

Good system design should follow the open‑closed principle; as business evolves, core code changes increase error risk. To handle expanding functionality without sacrificing performance, developers often use asynchronous thread pools, which introduce uncertainty. The author therefore designed a generic asynchronous processing SDK that can be easily integrated into various scenarios.

The SDK ensures that asynchronous processing does not block the main workflow while guaranteeing that method execution is effective and that data is not lost, thereby achieving eventual consistency.

Key advantages include a non‑intrusive design, independent database, scheduler, message queue, and a manual execution UI with unified authentication. It leverages Spring's transaction event mechanism so that even if asynchronous strategy parsing fails, business logic remains unaffected. If a method runs within a transaction, the event is processed after the transaction commits or rolls back, and fallback mechanisms handle failures unless the database, message queue, or method itself is faulty.

The core principle works as follows: after the container initializes beans, it scans all methods and caches those annotated with @AsyncExec. At runtime, an AOP aspect publishes an event, and a transaction event listener processes the asynchronous execution strategy.

Implementation details include the following annotation used for event listening:

@TransactionalEventListener(fallbackExecution = true, phase = TransactionPhase.AFTER_COMPLETION)

Components used by the SDK are Kafka (message queue), XXL‑Job (scheduler), MySQL (database), Spring AOP (aspect), and a Vue front‑end for the manual UI.

Design patterns applied are Strategy, Template Method, and Dynamic Proxy.

The SDK defines two database tables, async_req and async_log, to store request information and execution logs. Their creation scripts are:

CREATE TABLE `async_req` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `application_name` varchar(100) NOT NULL DEFAULT '' COMMENT '应用名称',
  `sign` varchar(50) NOT NULL DEFAULT '' COMMENT '方法签名',
  `class_name` varchar(200) NOT NULL DEFAULT '' COMMENT '全路径类名称',
  `method_name` varchar(100) NOT NULL DEFAULT '' COMMENT '方法名称',
  `async_type` varchar(50) NOT NULL DEFAULT '' COMMENT '异步策略类型',
  `exec_status` tinyint NOT NULL DEFAULT '0' COMMENT '执行状态 0:初始化 1:执行失败 2:执行成功',
  `exec_count` int NOT NULL DEFAULT '0' COMMENT '执行次数',
  `param_json` longtext COMMENT '请求参数',
  `remark` varchar(200) NOT NULL DEFAULT '' COMMENT '业务描述',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `idx_applocation_name` (`application_name`) USING BTREE,
  KEY `idx_exec_status` (`exec_status`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='异步处理请求';

CREATE TABLE `async_log` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `async_id` bigint NOT NULL DEFAULT '0' COMMENT '异步请求ID',
  `error_data` longtext COMMENT '执行错误信息',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `idx_async_id` (`async_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='异步处理日志';

Various diagrams (async strategy, security level, execution status, flowcharts) illustrate the workflow and state transitions.

Configuration is managed through Apollo. Example properties include enabling the SDK, thread pool sizes, retry counts, and other defaults:

# Switch (default off)
async.enabled=true

# Application name
spring.application.name=xxx

# Data source (Druid)
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/fc_async?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowMultiQueries=true&rewriteBatchedStatements=true
spring.datasource.username=user
spring.datasource.password=xxxx
spring.datasource.filters=config
spring.datasource.connectionProperties=config.decrypt=true;config.decrypt.key=yyy
spring.resources.add-mappings=true
spring.resources.static-locations=classpath:/static/

# Thread pool configuration (defaults)
async.executor.thread.corePoolSize=10
async.executor.thread.maxPoolSize=50
async.executor.thread.queueCapacity=10000
async.executor.thread.keepAliveSeconds=600

# Delete record after successful execution (default true)
async.exec.deleted=true

# Custom queue name prefix (default application name)
async.topic=${spring.application.name}

# Retry settings
async.exec.count=5
async.retry.limit=100
async.comp.limit=100
async.login=false

Typical usage steps are:

# Enable async globally
scm.async.enabled=true

# Annotate a Spring‑proxied method
@AsyncExec(type = AsyncExecEnum.SAVE_ASYNC, remark = "数据字典")

# Access the manual handling UI
http://localhost:8004/async/index.html

Important notes include ensuring the correct spring.application.name, proper queue naming (e.g., ${async.topic:${spring.application.name}_async_queue), implementing idempotency in business logic, using a single queue per application, and configuring scheduled retry (every 2 minutes) and compensation tasks (hourly for records older than one hour).

The article also shows effect screenshots and provides the GitHub repository URL:

https://github.com/xiongyanokok/fc-async.git
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

SDKSpringKafkadesign-patterns
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.