我应该在服务层记录 CRUD 方法吗?

Spa*_*age 2 java logging exception

我开始添加 slf4j 将自定义异常记录到我的项目中。我将日志添加到 ServiceImplementation 类中,其中有在 DaoImplementation 类中实现的 CRUD 方法。问题是:如果我的 CRUD 方法已经在 Dao 类中添加了日志和自定义异常,那么它们是否应该在其他类中具有相同的日志?例子:

public class SpringTeacherDao implements TeacherDao {
private static Logger logger = LoggerFactory.getLogger(SpringTeacherDao.class);

private JdbcTemplate jdbcTemplate;


@Autowired
public SpringTeacherDao(DataSource dataSource) {
    jdbcTemplate = new JdbcTemplate(dataSource);
}

@Override
public void create(Teacher teacher) {
    logger.debug("Add teacher status: in progress...");
    if (teacher == null) {
        String error = "Add teacher status: Error, teacher is null.";
        logger.warn(error);
        throw new UniversityDaoException(error);
    }
    String sql = "INSERT INTO teacher VALUES(?,?,?)";
    try {
        jdbcTemplate.update(sql, teacher.getID(), teacher.getName(), teacher.getSurname());
    }catch (DuplicateKeyException e){
        String duplicate = "Teacher id already exist";
        logger.warn(duplicate);
        throw new UniversityDaoException(duplicate);
    }
    logger.info("Add teacher status: Teacher has been added");
}
Run Code Online (Sandbox Code Playgroud)
public class TeacherServiceImpl implements TeacherService {
private static Logger logger = LoggerFactory.getLogger(TeacherServiceImpl.class);
private final TeacherDao teacherDao;
private final LectureDao lectureDao;
private final TeachersLectureDao teachersLectureDao;


public TeacherServiceImpl(TeacherDao teacherDao, LectureDao lectureDao, TeachersLectureDao teachersLectureDao) {
    this.teacherDao = teacherDao;
    this.lectureDao = lectureDao;
    this.teachersLectureDao = teachersLectureDao;
}

@Override
public void addTeacher(Teacher teacher) {
    teacherDao.create(teacher);
}
Run Code Online (Sandbox Code Playgroud)

Mir*_*uta 5

这不是一个与java相关的问题,而是编码实践问题。您可能会从您询问的每个人那里得到不同的答案,因为这可能与社区/公司/个人偏好等中建立的标准有关,因此:不要期望只有一个答案。

我对这个主题的看法(只是在多个层上记录异常,我不是在谈论传播/重新抛出/包装异常 - 因为那是另一个故事)如下:

如果给定层有任何特定内容要添加到日志中:记录它。例如:

  • DAO层可能会记录与异常的DB故障相关的信息
  • 服务层(调用该 DAO)可能具有更多执行该操作的上下文(即某些用户 ID 或操作特定数据),可以记录异常。
  • 可以有更多层,即下一层可以是某个控制器,它可以记录一些请求标识符(用于跟踪目的)或可能请求数据。

当然,这会导致异常被记录 3 次,每一次都会向日志中添加更多数据。但是,当您编写 DAO 类时,您无法保证服务是否会记录异常,因此它应该始终记录它(除非您有一个全局异常处理程序来记录所有未捕获的异常 - 但是:您无法保证服务不仅仅捕获异常而不记录)

顺便说一句 - 重新抛出异常的规则:始终将cause异常嵌入到您抛出的新异常中,这样您将看到完整的异常链。