Spring Boot + aop

好的,下面是一个真实的 Spring Boot 示例,展示如何使用 AOP 和自定义注解来记录请求参数、响应和耗时。

### 假设场景

我们构建一个简单的用户服务,包括用户的创建和获取。我们将在这两个方法上使用 AOP 来记录日志。

### 1. 创建自定义注解

首先,创建自定义注解 `@LogRequestResponse`。

```java
package com.example.demo.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogRequestResponse {
}
```

### 2. 创建 AOP 切面

接下来,创建一个切面类,处理日志逻辑。

```java
package com.example.demo.aspect;

import com.example.demo.annotation.LogRequestResponse;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Aspect
@Component
public class LoggingAspect {

    private static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);

    @Around("@annotation(LogRequestResponse)")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        // 记录请求参数
        Object[] args = joinPoint.getArgs();
        logger.info("Request Parameters: {}", Arrays.toString(args));

        // 记录开始时间
        long startTime = System.currentTimeMillis();

        // 执行目标方法
        Object proceed = joinPoint.proceed();

        // 记录结束时间
        long endTime = System.currentTimeMillis();

        // 记录响应
        logger.info("Response: {}", proceed);

        // 记录耗时
        logger.info("Execution time: {} ms", (endTime - startTime));

        return proceed;
    }
}
```

### 3. 创建用户服务

实现一个简单的`UserService`,包含创建和获取用户的方法。

```java
package com.example.demo.service;

import com.example.demo.annotation.LogRequestResponse;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service
public class UserService {
    private Map<Long, String> userDatabase = new HashMap<>();
    private long userIdCounter = 1;

    @LogRequestResponse
    public Long createUser(String userName) {
        Long userId = userIdCounter++;
        userDatabase.put(userId, userName);
        return userId;
    }

    @LogRequestResponse
    public String getUser(Long userId) {
        return userDatabase.get(userId);
    }
}
```

### 4. 创建控制器

创建控制器来调用用户服务。

```java
package com.example.demo.controller;

import com.example.demo.service.UserService;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/users")
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @PostMapping
    public Long createUser(@RequestBody String userName) {
        return userService.createUser(userName);
    }

    @GetMapping("/{id}")
    public String getUser(@PathVariable Long id) {
        return userService.getUser(id);
    }
}
```

### 5. 配置 Spring Boot

确保您的 `pom.xml` 中包含 Spring AOP 依赖。

```xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
```

### 6. 启动应用

您可以使用以下代码块在 `DemoApplication` 类中启动 Spring Boot 应用。

```java
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
```

### 7. 测试应用

启动应用后,您可以使用 Postman 或 CURL 测试 API。

#### 创建用户

```bash
curl -X POST -H "Content-Type: application/json" -d "John Doe" http://localhost:8080/users
```

#### 获取用户

```bash
curl http://localhost:8080/users/1
```

### 8. 日志输出示例

在控制台中,您应该能看到类似以下的输出:

```
2023-10-01 00:00:00 INFO Request Parameters: [John Doe]
2023-10-01 00:00:01 INFO Response: 1
2023-10-01 00:00:01 INFO Execution time: 5 ms

2023-10-01 00:00:02 INFO Request Parameters: [1]
2023-10-01 00:00:02 INFO Response: John Doe
2023-10-01 00:00:02 INFO Execution time: 1 ms
```

### 注意事项

1. **异常处理**:您可以扩展 AOP 来捕获异常并记录错误信息。
  
2. **敏感数据**:在处理请求时,确保不在日志中记录敏感信息。

3. **性能**:定期检查日志的生成,确认不会影响系统性能。

通过这种实现方式,您可以便捷地记录请求和响应的参数以及处理时间,有效提高系统的可监控性和调试能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值