Lambda表达式可实现轻量级AOP切面,通过函数式接口封装业务逻辑并在执行前后注入监控行为,无需框架、无代理开销,适用于单点增强;但需手动包装调用点,不支持全局拦截或原逻辑跳过。

可以用Lambda表达式实现轻量级AOP切面,核心是把业务逻辑封装成函数式接口的实例,再用包装逻辑在执行前后注入监控行为——不依赖框架、无代理开销、适合单点增强或工具类场景。
定义统一的函数式接口
先声明一个支持泛型的函数式接口,覆盖常见调用模式:
- 入参可变(用Object...)、返回值可为任意类型,便于适配不同方法
- 接口方法名语义清晰,比如execute或runWithMonitor
示例:
@FunctionalInterface
public interface MonitoredTask<R> {
R execute(Object... args) throws Throwable;
}
编写带监控逻辑的执行器
写一个静态工具方法,接收Lambda和参数,在执行前后打印变量、耗时、异常等:
- 记录开始时间、方法标识(可用Thread.currentThread().getStackTrace()简单提取)
- 捕获并打印入参(Arrays.toString(args))、返回值、异常堆栈
- 避免直接打印敏感字段,生产环境建议加白名单过滤
示例调用方式:
String result = MonitorUtil.execute(
() -> userService.getUserById(1001L),
"getUserById", 1001L
);
其中MonitorUtil.execute内部会做日志埋点和异常包装。
适配Controller或Service中的具体方法
对已有方法不做侵入修改,仅用Lambda包装即可启用监控:
- 原方法保持干净:public User findUser(Long id) { ... }
- 调用处改为:MonitoredTask<User> task = () -> findUser(id); task.execute(id);
- 若需复用监控逻辑,可将task封装为Supplier/Function,配合Stream或Optional链式使用
补充:与Spring AOP或JDK Proxy的区别
这种Lambda方案本质是“主动调用+手动包装”,不是运行时自动织入:
- ✅ 无反射、无代理、无字节码操作,性能开销最小
- ✅ 支持private/static/构造方法等任意可见性方法
- ❌ 不具备全局拦截能力,需显式包裹每个目标调用点
- ❌ 无法像@Around那样控制是否执行原逻辑(除非在Lambda体内加条件判断)

















