一、什么是模版+回调
你肯定见到过类似这样的 代码
TransactionUtil.doInTransactionWithRequires(() -> { });而doInTransactionWithRequires 这个方法接收一个函数式方法 supplier 然后内部去调用这个方法
doInTransactionWithRequires(Suppler<T> supplier) { T result = supplier.get() }这个就是模版+回调
模板负责“流程骨架”, 回调负责“变化点注入”。
二、先看“纯模板方法”的问题
传统的模板方法模式长这样:
public abstract class AbstractTask { public final void execute() { before(); doExecute(); after(); } protected void before() {} protected abstract void doExecute(); protected void after() {} }子类继承:
public class OrderTask extends AbstractTask { @Override protected void doExecute() { } }这个方案的问题在工程里很明显:
强依赖继承
子类越来越多
一个类只能继承一个父类
行为组合非常困难
所以在大型框架里,纯继承模板几乎不用了。
三、模板 + 回调:把“变化”从继承变成参数
核心思想
不再靠子类重写方法, 而是把“变化的逻辑”作为参数传进去
这个“参数”,就是 回调(Callback)。
四、源码案例Spring 的TransactionTemplate:
再看 Spring 提供的 TransactionTemplate:
transactionTemplate.execute(status -> { userDao.update(user); orderDao.create(order); return result; });对应源码里的核心逻辑:
TransactionStatus status = transactionManager.getTransaction(definition); try { T result = action.doInTransaction(status); transactionManager.commit(status); return result; } catch (Exception ex) { transactionManager.rollback(status); throw ex; }五、源码案例 JdbcTemplate
Spring JDBC 里最经典的 JdbcTemplate:
jdbcTemplate.query( "select * from user", (rs, rowNum) -> new User(rs.getLong("id"), rs.getString("name")) );传进去的 RowMapper,就是回调。
JdbcTemplate 内部做的事是固定的:
变化点只有一行:
rowMapper.mapRow(rs, rowNum);六、总结
模板 + 回调并不等于“继承 + 抽象方法”。 在现代 Java 项目里,它更多以 函数式接口 + Lambda 的形式出现。
不管是公司事务工具类、Spring TransactionTemplate,还是 JdbcTemplate,本质都是同一套思想: 模板负责流程,回调负责变化。