Java中可通过自定义@LogExecution注解结合AOP切面实现方法执行日志自动打印:定义运行时注解标记方法,编写@Around切面拦截并记录开始、完成或异常信息及耗时,需确保目标方法为Spring Bean且为public。

Java 中可以通过自定义注解 + AOP(面向切面编程)实现在控制台打印方法执行日志,无需在每个方法里手动写 System.out.println。核心思路是:定义一个注解(如 @LogExecution),用 AOP 拦截被该注解标记的方法,在其执行前后自动输出日志。
1. 定义日志注解
创建一个运行时保留的自定义注解,用于标记需要记录执行日志的方法:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecution {
String value() default ""; // 可选描述,如 "用户登录校验"
}2. 编写 AOP 切面类
使用 Spring AOP(需引入 spring-boot-starter-aop),编写切面,在方法执行前后打印日志:
@Aspect
@Component
public class LoggingAspect {
<pre class="brush:php;toolbar:false;">private static final Logger log = LoggerFactory.getLogger(LoggingAspect.class);
@Around("@annotation(logExecution)")
public Object logExecutionTime(ProceedingJoinPoint joinPoint, LogExecution logExecution) throws Throwable {
String methodName = joinPoint.getSignature().toShortString();
String desc = StringUtils.hasText(logExecution.value()) ?
"(" + logExecution.value() + ")" : "";
log.info("▶ 开始执行: {} {}", methodName, desc);
long start = System.currentTimeMillis();
try {
Object result = joinPoint.proceed();
long duration = System.currentTimeMillis() - start;
log.info("✔ 执行完成: {} {},耗时: {}ms", methodName, desc, duration);
return result;
} catch (Exception e) {
long duration = System.currentTimeMillis() - start;
log.error("✘ 执行异常: {} {},耗时: {}ms,异常: {}",
methodName, desc, duration, e.getMessage());
throw e;
}
}}
说明:
- 使用
@Around可控制方法执行、获取返回值、捕获异常、统计耗时; - 推荐用
LoggerFactory(SLF4J)替代System.out.println,便于后续对接日志框架(如 Logback); - 若坚持用控制台打印,可将
log.info(...)替换为System.out.println(...),但不建议用于生产环境。
3. 在方法上使用注解
在任意 Spring 管理的 Bean 方法上添加 @LogExecution:
@Service
public class UserService {
<pre class="brush:php;toolbar:false;">@LogExecution("查询用户详情")
public User getUserById(Long id) {
// 模拟业务逻辑
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return new User(id, "张三");
}}
调用该方法时,控制台会输出类似:
▶ 开始执行: UserService.getUserById(Long) (查询用户详情) ✔ 执行完成: UserService.getUserById(Long) (查询用户详情),耗时: 102ms
4. 注意事项
- 确保目标类是 Spring Bean(加
@Service/@Component等),否则 AOP 不生效; - AOP 默认只对 public 方法生效(CGLIB/JDK 动态代理限制);
- 若项目未启用 AOP,需确认已添加依赖并开启支持(Spring Boot 默认开启,传统 Spring 需配置
<aspectj-autoproxy></aspectj-autoproxy>); - 如需更细粒度控制(如仅记录入参/出参),可在
joinPoint中获取args或result并格式化输出。
不复杂但容易忽略:注解本身不会起作用,必须配合 AOP 切面和 Spring 容器管理才能触发日志打印。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











