📖 概述
什么是 JmsBasic-Lib?
JmsBasic-Lib 是一个轻量级的 Java 基础组件库,提供了通用的基础设施接口和工具类。 它是整个 JMS 系列框架的基石,为其他模块(如 JmsFile、JmsImage 等)提供统一的资源管理、日志适配、执行器模式等核心能力。
- 统一的资源生命周期管理
- 灵活的日志适配器机制
- 标准化的执行器模式
- 简洁的拦截器设计
- 完善的异常处理体系
Java 基础组件库
Version 1.x.xJmsBasic-Lib 是一个轻量级的 Java 基础组件库,提供了通用的基础设施接口和工具类。 它是整个 JMS 系列框架的基石,为其他模块(如 JmsFile、JmsImage 等)提供统一的资源管理、日志适配、执行器模式等核心能力。
Resource 是资源管理的核心接口,定义了资源的初始化和销毁行为。
// Resource 接口定义
public interface Resource {
void init();
void destroy();
}// 实现 Resource 接口
public class MyResource implements Resource {
private Connection connection;
@Override
public void init() {
// 初始化资源
this.connection = new Connection();
this.connection.connect();
}
@Override
public void destroy() {
// 释放资源
if (this.connection != null) {
this.connection.close();
this.connection = null;
}
}
}
// 使用
MyResource resource = new MyResource();
resource.init();
// ... 使用资源 ...
resource.destroy();
AutoCloseableResource 继承自 Resource 和 AutoCloseable,
支持 try-with-resources 语法,让资源管理更安全、更简洁。
// AutoCloseableResource 接口定义
public interface AutoCloseableResource extends Resource, AutoCloseable {
@Override
default void close() {
destroy();
}
}// 实现 AutoCloseableResource 接口
public class DatabaseConnection implements AutoCloseableResource {
private Connection connection;
private ResourceState state = ResourceState.UNINITIALIZED;
@Override
public void init() {
if (this.state != ResourceState.UNINITIALIZED) {
throw new JmsBasicException("资源已初始化");
}
this.connection = DriverManager.getConnection("jdbc:mysql://localhost/db");
this.state = ResourceState.ACTIVE;
}
@Override
public void destroy() {
if (this.state == ResourceState.DESTROYED) {
return;
}
if (this.connection != null) {
try {
this.connection.close();
} catch (SQLException e) {
throw new JmsBasicException("关闭连接失败", e);
}
}
this.state = ResourceState.DESTROYED;
}
public Connection getConnection() {
if (this.state != ResourceState.ACTIVE) {
throw new JmsBasicException("资源未激活");
}
return this.connection;
}
}
// ✅ 推荐用法:try-with-resources
try (DatabaseConnection db = new DatabaseConnection()) {
db.init();
// ... 使用数据库连接 ...
// 退出 try 块时自动调用 close() → destroy()
} catch (Exception e) {
logger.error("数据库操作失败", e);
}
// ❌ 传统用法:需要手动关闭
DatabaseConnection db = null;
try {
db = new DatabaseConnection();
db.init();
// ... 使用数据库连接 ...
} finally {
if (db != null) {
db.destroy(); // 手动调用,容易忘记
}
}
1. 必须先调用 init() 初始化资源
2. try-with-resources 会在退出 try 块时自动调用 close()(即 destroy())
3. 不要在 try 块内手动调用 destroy(),避免重复关闭
ResourceState 定义了资源的三种生命周期状态。
| 状态 | 说明 | 典型场景 |
|---|---|---|
UNINITIALIZED |
未初始化 | 对象刚创建,尚未调用 init() |
ACTIVE |
活动中 | 已初始化,可正常使用 |
DESTROYED |
已销毁 | 已调用 destroy(),不可再用 |
// 状态流转示例
MyResource resource = new MyResource();
// 当前状态:UNINITIALIZED
resource.init();
// 当前状态:ACTIVE
// ... 使用资源 ...
resource.destroy();
// 当前状态:DESTROYED已销毁的资源不能再次使用!尝试访问会抛出异常。
Handler 是执行器模式的核心,定义了标准的处理流程。
// Handler 接口定义
public interface Handler<T> {
T handle();
}
Executor 负责执行 Handler,实现解耦。
// Executor 接口定义
public interface Executor<T extends Handler<?>, U> {
U execute(T handler);
}// ① 定义业务 Handler
public class DataProcessHandler implements Handler<String> {
private String inputData;
public DataProcessHandler(String inputData) {
this.inputData = inputData;
}
@Override
public String handle() {
// 处理数据
return "Processed: " + inputData.toUpperCase();
}
}
// ② 实现 Executor
public class DataExecutor implements Executor<DataProcessHandler, String> {
@Override
public String execute(DataProcessHandler handler) {
System.out.println("开始执行...");
String result = handler.handle();
System.out.println("执行完成:" + result);
return result;
}
}
// ③ 使用
DataExecutor executor = new DataExecutor();
executor.execute(new DataProcessHandler("hello"));
// 输出:开始执行...
// 执行完成:Processed: HELLO执行器模式将"做什么"(Handler)和"怎么做"(Executor)分离,符合开闭原则,易于扩展和维护。
Logger 提供统一的日志记录规范。
// Logger 接口定义
public interface Logger {
void debug(String var1);
void info(String var1);
void warn(String var1);
void error(String var1);
void error(String var1, Throwable var2);
}
LogAdapter 通过反射机制自动适配任意日志框架(如 SLF4J、Log4j、JUL 等)。
// 适配 SLF4J Logger
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Logger slf4jLogger = LoggerFactory.getLogger(MyClass.class);
Logger jmsLogger = LogAdapter.getLogger(slf4jLogger);
jmsLogger.info("这是一条信息");
jmsLogger.error("发生错误", new Exception("test"));
// 适配 Log4j Logger
org.apache.log4j.Logger log4jLogger = org.apache.log4j.Logger.getLogger(MyClass.class);
Logger jmsLog4jAdapter = LogAdapter.getLogger(log4jLogger);
jmsLog4jAdapter.warn("警告信息");// ① LogAdapter 通过反射获取目标对象的方法
Method debugMethod = target.getClass().getMethod("debug", String.class);
Method infoMethod = target.getClass().getMethod("info", String.class);
Method errorMethod = target.getClass().getMethod("error", String.class, Throwable.class);
// ② 缓存到 Map 中,避免重复反射
methodMap.put("debug", debugMethod);
methodMap.put("info", infoMethod);
methodMap.put("error", errorMethod);
// ③ 调用时使用反射
methodMap.get("info").invoke(target, message);public class UserService {
// 使用 LogAdapter 适配 SLF4J
private static final Logger logger =
LogAdapter.getLogger(org.slf4j.LoggerFactory.getLogger(UserService.class));
public void createUser(String username) {
logger.debug("开始创建用户:" + username);
try {
// ... 业务逻辑 ...
logger.info("用户创建成功:" + username);
} catch (Exception e) {
logger.error("用户创建失败:" + username, e);
throw new RuntimeException("创建失败", e);
}
}
}
Interceptor 是一个标记接口,用于标识拦截器类型。
// Interceptor 接口定义
public interface Interceptor {
// 标记接口,无方法定义
}// 实现业务拦截器
public class ValidationInterceptor implements Interceptor {
public boolean validate(Object data) {
if (data == null) {
return false;
}
// ... 验证逻辑 ...
return true;
}
}
// 在业务中使用
ValidationInterceptor interceptor = new ValidationInterceptor();
if (interceptor.validate(userData)) {
// 验证通过,继续处理
process(userData);
} else {
// 验证失败,中断流程
handleError();
}
JmsBasicException 是所有基础模块异常的父类,继承自 RuntimeException。
// 异常类定义
public class JmsBasicException extends RuntimeException {
// 构造方法
public JmsBasicException() { super(); }
public JmsBasicException(String message) { super(message); }
public JmsBasicException(String message, Throwable cause) { super(message, cause); }
public JmsBasicException(Throwable cause) { super(cause); }
}// ① 抛出简单异常
throw new JmsBasicException("资源未找到");
// ② 抛出带原因的异常
try {
// ... 可能失败的代码 ...
} catch (IOException e) {
throw new JmsBasicException("IO 操作失败", e);
}
// ③ 捕获并处理
try {
resource.init();
} catch (JmsBasicException e) {
logger.error("初始化失败", e);
// 恢复逻辑...
}// ① 定义资源类(使用 AutoCloseableResource)
public class DatabaseResource implements AutoCloseableResource {
private Connection connection;
private ResourceState state = ResourceState.UNINITIALIZED;
@Override
public void init() {
if (this.state != ResourceState.UNINITIALIZED) {
throw new JmsBasicException("资源已初始化");
}
this.connection = DriverManager.getConnection("jdbc:mysql://localhost/db");
this.state = ResourceState.ACTIVE;
}
@Override
public void destroy() {
if (this.state == ResourceState.DESTROYED) {
return;
}
if (this.connection != null) {
try {
this.connection.close();
} catch (SQLException e) {
throw new JmsBasicException("关闭连接失败", e);
}
}
this.state = ResourceState.DESTROYED;
}
public Connection getConnection() {
if (this.state != ResourceState.ACTIVE) {
throw new JmsBasicException("资源未激活");
}
return this.connection;
}
}
// ② 定义业务 Handler
public class QueryHandler implements Handler<ResultSet> {
private DatabaseResource resource;
private String sql;
public QueryHandler(DatabaseResource resource, String sql) {
this.resource = resource;
this.sql = sql;
}
@Override
public ResultSet handle() {
try (Statement stmt = resource.getConnection().createStatement()) {
return stmt.executeQuery(sql);
} catch (SQLException e) {
throw new JmsBasicException("查询执行失败", e);
}
}
}
// ③ 定义拦截器
public class SqlValidationInterceptor implements Interceptor {
public boolean validate(String sql) {
// 防止 SQL 注入
if (sql.contains("DROP") || sql.contains("DELETE")) {
return false;
}
return true;
}
}
// ④ 使用方式 A:传统方式
DatabaseResource db = new DatabaseResource();
db.init();
SqlValidationInterceptor validator = new SqlValidationInterceptor();
if (validator.validate("SELECT * FROM users")) {
QueryHandler handler = new QueryHandler(db, "SELECT * FROM users");
ResultSet rs = handler.handle();
// ... 处理结果集 ...
}
db.destroy();
// ⑤ 使用方式 B:try-with-resources(推荐)
try (DatabaseResource db = new DatabaseResource()) {
db.init();
SqlValidationInterceptor validator = new SqlValidationInterceptor();
if (validator.validate("SELECT * FROM users")) {
QueryHandler handler = new QueryHandler(db, "SELECT * FROM users");
ResultSet rs = handler.handle();
// ... 处理结果集 ...
}
// 自动调用 db.destroy(),无需手动关闭
} catch (Exception e) {
logger.error("数据库操作失败", e);
}| 组件 | 类型 | 职责 | 典型场景 |
|---|---|---|---|
Resource |
接口 | 资源生命周期管理 | 数据库连接、文件流、网络套接字 |
AutoCloseableResource |
接口 | 自动关闭资源(try-with-resources) | 需要自动资源清理的场景 |
ResourceState |
枚举 | 标识资源状态 | 状态检查、流程控制 |
Handler |
接口 | 封装处理逻辑 | 业务处理、数据转换 |
Executor |
接口 | 执行 Handler | 任务调度、流程编排 |
Logger |
接口 | 统一日志规范 | 日志记录、调试追踪 |
LogAdapter |
工具类 | 适配第三方日志框架 | SLF4J、Log4j、JUL 适配 |
Interceptor |
接口 | 标记拦截器 | 权限校验、数据验证 |
JmsBasicException |
异常类 | 统一异常处理 | 错误报告、异常包装 |
资源管理 Resource,状态流转要清晰
AutoCloseableResource,try-with-resources 更省心
Handler 封装逻辑,Executor 来执行
日志适配 LogAdapter,多框架都兼容
拦截器做校验,异常处理 JmsBasic