为了账号安全,请及时绑定邮箱和手机立即绑定

Spring Boot开发中常见的坑及其避坑指南

Spring Boot 常见坑

看看我详细制作的视频,可以订阅我的频道加入我们的大家庭。您的支持对我来说意义非凡!非常感谢!

@Component
public class DateUtils {
    public static LocalDate parse(String date) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); // 日期格式可以按需调整为 "yyyy-MM-dd"
        try {
            return LocalDate.parse(date, formatter);
        } catch (DateTimeParseException e) {
            e.printStackTrace();
            return null; // 或者根据实际情况处理异常
        }
    }
}

工具类通常包含静态方法,不需要 Spring 的依赖注入或类似的生命周期管理。

在工具类上使用 @Component 是不必要的,因为它不需要被 Spring 创建或管理。

过度使用@Component可能带来的影响是:

不必要的复杂性: 在没有实际需要的情况下引入@Component会增加应用程序的不必要的复杂性。
资源管理: Spring会为工具类创建并管理一个bean,这实际上是对资源的一种不必要的消耗。
误导性语义: 这可能会误导其他开发人员认为这个类有需要由Spring来管理的依赖或状态,但实际上并没有这样的需求。

像 DateUtils 这样的工具类,如果只包含静态方法且不需要任何 Spring 功能,最好别用 @Component。最合适的办法就是不加任何 Spring 注解定义这个类。

2. @ResponseBody 注解使用不当

  • 错误:滥用 @ResponseBody 注解于所有控制器中。
  • 提示:对于 RESTful API,建议使用 @RestController 注解以避免重复。
    @RestController (注:注解控制器)
@RestController
@RequestMapping("/api/employees")
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;

    @GetMapping
    @ResponseBody
    /* 获取所有员工信息的映射 */
    public List<Employee> getAllEmployees() {
        return employeeService.getAllEmployees();
    }
}

@RestController 与 @Controller:

@RestController 是@Controller的一个特殊版本,它结合了@Controller注解的功能和@ResponseBody的功能。

@Controller 通常用于 MVC 架构中的控制器,其中方法返回视图页面(如 HTML、JSP 等)。
@RestController 通常用于 RESTful API 的控制器,其中方法直接返回数据(如 JSON、XML 等)。

@RestController: 的作用:

当你在一个类上使用 @RestController 注解时,意味着该类中的所有方法默认带有 @ResponseBody 注解。这意味着每个方法的返回值会直接作为 JSON 或 XML 数据返回。

@ResponseBody 注解对 @RestController 方法的影响是:

在使用@RestController注解的类中的方法显式添加@ResponseBody注解是多余的,实际上并不会提供任何额外的功能。它不会导致错误或负面影响,也不会对应用程序的行为表现产生负面影响,但会增加代码的冗余度。

3. 不正确的 @Autowired 注入方式

  • 错误:使用 @Autowired 注入字段。
  • 提示:建议使用构造函数注入,这样可以提高可测试性并保持不可变性。

    @Service  
    /* 服务类 */
    public class EmployeeService {  

        @Autowired  
        /* 依赖注入 */
        private EmployeeRepository employeeRepository;  

        /* 获取所有员工信息 */
        public List<Employee> getAllEmployees() {  
            return employeeRepository.findAll();  
        }  
    }  

在你的 EmployeeService 类中,使用构造器注入(而不是在字段上使用 @Autowired)通常被认为是一个更好的做法。构造器注入提高了可测试性、可读性,并有助于更好地管理依赖关系。

这里是如何通过构造注入来重构你的 EmployeeService 类代码:

    public class EmployeeService {  

        private final EmployeeRepository employeeRepository;  

        // 构造注入  
        public EmployeeService(EmployeeRepository employeeRepository) {  
            this.employeeRepository = employeeRepository;  
        }  

        public List<Employee> getAllEmployees() {  
            return employeeRepository.findAll();  
        }  
    }

关于构造器注入的好处,如下:

  • 测试性: 通过构造器注入,你可以在为 EmployeeService 编写单元测试时轻松模拟依赖。
  • 依赖关系明确: 它使依赖关系明确,提高可读性,减少空指针异常。
  • 初始化后依赖项无法更改: 一旦初始化,依赖项(例如本例中的 employeeRepository)无法更改,从而促进不可变。

不要在字段上使用@Autowired:

@Autowired不宜直接用于字段:

  • 这会使代码耦合紧密,并可能导致依赖关系不那么清晰。
  • 构造函数注入通过在构造函数的参数列表中明确指出依赖关系来解决了这些问题的出现。

4. application.properties 管理失误

  • 错误:在 application.properties 文件中硬编码配置值。
  • 提示:利用 Spring 配置文件(如 application-{profile}.properties)来管理不同环境(如开发、测试和生产)的配置。

5. 异常处理不当

  • 失误:未实现全局异常处理机制。
  • 提示:使用 @ControllerAdvice 来一致地处理异常。

你的 GlobalExceptionHandler 设置得很到位,在你的 Spring Boot 项目中全局处理异常。通过集中处理异常,你可以保持错误响应的一致性,并简化应用中的错误管理。这不仅提高了可维护性,并且通过提供丰富且一致的错误信息来增强用户体验。

    @RestController  
    @RequestMapping("/api/employees")  
    public class EmployeeController {  

        @Autowired  
        private EmployeeService employeeService;  

        @GetMapping("/{id}")  
        public ResponseEntity<Employee> getEmployeeById(@PathVariable Long id) {  
            Employee employee = employeeService.getEmployeeById(id);  
            if (employee == null) {  
                throw new EmployeeNotFoundException("未找到ID为" + id + "的员工");  // 抛出异常:未找到具有该ID的员工
            }  
            return ResponseEntity.ok(employee);  
        }  

        // 其他方法  
    }
@ControllerAdvice  
public class GlobalExceptionHandler {  

    @ExceptionHandler(EmployeeNotFoundException.class)  
    public ResponseEntity<String> handleEmployeeNotFoundException(EmployeeNotFoundException ex, WebRequest request) {  
        return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);  
    }  

    @ExceptionHandler(Exception.class)  
    public ResponseEntity<String> handleGlobalException(Exception ex, WebRequest request) {  
        return new ResponseEntity<>("出现了一个问题: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);  
    }  
}

6. 低效的日志记录习惯

  • 错误:不理解日志级别以及记录敏感数据。
  • 提示:
    — 理解并使用适当的日志级别(ERROR, WARN, INFO, DEBUG, TRACE),即(错误、警告、信息、调试、跟踪)。
    — 使用Spring配置为不同的环境配置日志级别。
    — 不要记录敏感信息,如用户ID和交易ID。

了解更多关于Redis端到端测试的全面方法,并观看我的详细介绍YouTube视频

谢谢,继续加油哦!

ajtech

感谢您一直读到最后,在您离开之前,还有一句话想对您说。

  • 请考虑拍手关注作者哦! 👏 掌声鼓励!
  • 关注我们的YouTube频道,不要错过哦!

跟着我,你会发现更多精彩的内容

关注我吧,我在 Medium 上点击这里关注我

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消