微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何避免 DtoMappers 层中的服务

如何解决如何避免 DtoMappers 层中的服务

美好的一天,我有一个基于 Spring Boot 的后端,我们正在使用自己的库将 JPA 实体转换为 Dto(基于反射的库工作)。 问题是,我们将服务层直接注入到一些映射器中。假设我有一个 UserEntityUserDto。 UserDto 有一个名为 avatar 的字段,头像存储在 S3 中。 因此,为了构建 UserDto,我们使用了这样的代码

@Component
class UserMapper {

 @Inject
 S3Service s3Service;

 public UserDto toDto(UserEntity entity){
     UserDto dto = new UserDto();
     BeanUtils.copy(entity,dto);
     dto.setAvatar(s3Service.getAvatarByUser(entity));

}

}

我不喜欢这种方法,因为 Mapper 必须对 Service layer 一无所知。然而,这个映射器也被其他映射器使用。如果我想返回一个 OrderDto,它有一个嵌套的 UserDto,所以 OrderDto 在内部调用 UserMapper。 Mappers 是否有免费服务的最佳实践?

到目前为止,我尝试了以下方法

  1. 将头像存储在 ThreadLocal 缓存中。当控制器调用服务获取用户时,服务会将用户的头像存储在 ThreadLocal 中,然后 Mapper 将从 ThreadLocal 缓存中获取。缺点 - 很难测试,需要我制作 Mocks
  2. 创建一个名为 UserWithAvatar 的单独 POJO,用于存储 UserEntity entity;String avatar 并为 UserWithAvatar 而不是 UserEntity 创建映射器。缺点 - 正如我所说,此映射器将由 OrderMapper 使用,而订单映射器采用带有嵌套 OrderEntity 而不是 UserEntity
  3. UserWithAvatar

解决方法

我认为映射器应该在服务内部,但我会尝试满足您的要求

你有两个选择:

  1. 您将服务和映射器注入控制器,将实体返回控制器并在返回响应之前使用映射器将其映射

  2. 使用事件发布来发布一个事件,然后映射器捕获并生成映射。之后,您可以直接将 dto 返回给控制器或生成另一个事件。 (事件发布默认是同步的,所以你不必担心并发问题)

事件发布是通过 spring 完成的,导致代码非常解耦,其中发布者对事件订阅者一无所知,因此这两个层可以位于 2 个独立的层中,彼此不了解任何信息

易于遵循的指南:https://www.baeldung.com/spring-events

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。