CGLIB可通过生成子类代理无接口的普通类,结合ThreadLocal封装的TransactionManager实现MySQL事务控制,但需手动管理连接与提交/回滚,且不支持异步和嵌套事务等复杂场景。

CGLIB 可以代理没有实现接口的普通类(如 Spring 中的 Service 类),通过字节码增强生成子类来实现代理。要为这类 Service 方法添加 MySQL 事务控制,核心思路是:在代理方法执行前后,手动管理数据库连接、开启/提交/回滚事务。注意——CGLIB 本身不提供事务能力,它只负责拦截方法调用;事务逻辑需你自行封装(比如基于 JDBC 或 DataSource)。
1. 添加 CGLIB 依赖
确保项目中引入 CGLIB(Spring 已内置,若单独使用需显式添加):
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.3.0</version> </dependency>
2. 编写事务管理工具类(基于 JDBC)
你需要一个能获取 Connection、控制 commit/rollback 的工具类。例如:
假设你已有一个 DataSource(如 HikariCP 或 Druid),可封装如下:
客服回复模板。售前咨询、售后处理、退换货、投诉回复、好评引导、升级处理、行业FAQ、满意度挽回。Customer service reply templates for pre-sale, after-sale, returns, complaints, escalation, FAQ generation, s...
立即学习“Java免费学习笔记(深入)”;
public class TransactionManager {
private static final ThreadLocal<Connection> CONNECTION_HOLDER = new ThreadLocal<>();
private static DataSource dataSource;
public static void setDataSource(DataSource ds) {
dataSource = ds;
}
public static Connection getConnection() throws SQLException {
Connection conn = CONNECTION_HOLDER.get();
if (conn == null) {
conn = dataSource.getConnection();
conn.setAutoCommit(false); // 关键:关闭自动提交
CONNECTION_HOLDER.set(conn);
}
return conn;
}
public static void commit() {
Connection conn = CONNECTION_HOLDER.get();
if (conn != null) {
try {
conn.commit();
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
closeConnection();
}
}
}
public static void rollback() {
Connection conn = CONNECTION_HOLDER.get();
if (conn != null) {
try {
conn.rollback();
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
closeConnection();
}
}
}
private static void closeConnection() {
Connection conn = CONNECTION_HOLDER.get();
if (conn != null) {
try {
conn.close();
} catch (SQLException ignored) {}
CONNECTION_HOLDER.remove();
}
}
}
3. 使用 CGLIB 创建事务代理
通过 Enhancer 设置回调,对目标 Service 的所有非 final 方法进行拦截,在 invoke 中统一加事务逻辑:
public class TransactionProxy implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
boolean isTransactional = method.isAnnotationPresent(Transactional.class);
if (!isTransactional) {
return proxy.invokeSuper(obj, args); // 非事务方法直接放行
}
try {
Object result = proxy.invokeSuper(obj, args);
TransactionManager.commit();
return result;
} catch (Exception e) {
TransactionManager.rollback();
throw e;
}
}
}
// 创建代理实例
public class ProxyFactory {
public static <T> T createTransactionalProxy(T target) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(new TransactionProxy());
return (T) enhancer.create();
}
}
使用时:
UserService userService = new UserService(); // 没有实现接口的普通类
UserService proxy = ProxyFactory.createTransactionalProxy(userService);
// 调用带 @Transactional 注解的方法,自动触发事务
proxy.saveUser(new User("Alice")); // ✅ 自动开启、提交或回滚事务
4. 注意事项与限制
- 目标类不能是 final,方法也不能是 final —— CGLIB 是通过继承生成子类实现的
-
构造器参数会被忽略:enhancer.create() 默认调用无参构造;若目标类只有有参构造,需用
enhancer.setCallbacks(...)+enhancer.setConstructorArguments(...) - 事务边界仅限当前线程:ThreadLocal 管理 Connection,天然支持单线程事务,但不适用于异步(如 CompletableFuture)、线程池场景
- 不推荐在生产中裸写事务代理:Spring 的 @Transactional 底层就用了类似机制(AOP + CGLIB/JDK Proxy),且处理了嵌套事务、传播行为、异常分类回滚等复杂问题;自己实现易出错,建议优先用 Spring 声明式事务

















