核心是用自定义注解标记方法,反射读取注解后结合动态代理在方法执行前后织入事务逻辑:先定义@Retention(RUNTIME)的@Transactional注解,再通过InvocationHandler反射判断并触发beginTransaction/commit/rollback,最后用Proxy.newProxyInstance生成代理对象实现声明式事务控制。

Java 中通过反射 + 注解实现声明式事务拦截,核心是:用自定义注解标记方法(如 @Transactional),在运行时用反射获取该注解,再结合动态代理(如 JDK Proxy 或 CGLIB)在方法执行前后织入事务开启、提交或回滚逻辑。
1. 定义事务注解
先创建一个运行时保留的注解,用于标记需要事务管理的方法:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Transactional {
boolean rollbackForException() default true;
}这个注解不带逻辑,仅作“标记”用途,后续靠反射读取它。
2. 编写事务拦截器(基于 JDK 动态代理)
代理类在调用目标方法前开启事务,成功后提交,异常时回滚。关键步骤依赖反射判断方法是否标注了 @Transactional:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 通过
method.getAnnotation(Transactional.class)检查注解存在性 - 若存在,调用
beginTransaction();方法执行完调用commitTransaction() - 若抛异常且注解允许回滚,调用
rollbackTransaction()
public class TransactionInvocationHandler implements InvocationHandler {
private final Object target;
<pre class="brush:php;toolbar:false;">public TransactionInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Transactional annotation = method.getAnnotation(Transactional.class);
if (annotation == null) {
return method.invoke(target, args); // 非事务方法,直接执行
}
beginTransaction();
try {
Object result = method.invoke(target, args);
commitTransaction();
return result;
} catch (Exception e) {
if (annotation.rollbackForException()) {
rollbackTransaction();
}
throw e;
}
}
private void beginTransaction() { /* 实际开启数据库事务 */ }
private void commitTransaction() { /* 提交 */ }
private void rollbackTransaction() { /* 回滚 */ }}
3. 创建代理对象并使用
利用反射获取目标类的 Class,再生成代理实例:
- 确保目标类实现接口(JDK Proxy 要求),例如
UserService实现UserDao - 用
Proxy.newProxyInstance()创建代理,传入TransactionInvocationHandler - 调用代理对象的方法时,自动触发事务逻辑
UserDao userService = new UserServiceImpl();
UserDao proxy = (UserDao) Proxy.newProxyInstance(
UserDao.class.getClassLoader(),
new Class[]{UserDao.class},
new TransactionInvocationHandler(userService)
);
<p>proxy.updateUser(user); // 此时会走事务拦截流程4. 补充说明(Spring 是怎么做的)
Spring 的 @Transactional 底层正是这套思路的增强版:
- 用
BeanPostProcessor在 Bean 初始化后生成代理(支持接口代理和 CGLIB 类代理) - 事务属性解析更复杂(传播行为、隔离级别、只读、超时等),但起点仍是反射读取注解
- 事务管理委托给
PlatformTransactionManager,与具体数据源解耦
自己手写时不必重复造轮子,但理解反射如何驱动注解行为,是掌握 Spring 声明式事务的关键。

















