繁体   English   中英

如何使用 Spring Boot 在整体应用程序中设计“删除用户流”?

[英]How to design "delete user flow" in monolith application with Spring Boot?

我有一个整体 spring 启动应用程序,我有一个程序用户。 我想创建一个端点来删除用户,但我的问题是与用户相关的实体和 Jpa 存储库接口太多。 当我想删除一个用户时,我需要在相关的删除服务中注入如此多的存储库接口,比如:

    @Service
    public class DeletionService {
    
        private static final int S3_DELETION_KEY_LIMIT = 1000;
    
        private final OfficeRepository officeRepository;
        private final AdvertRepository advertRepository;
        private final UserRepository userRepository;
        private final AdvertSearchRepository advertSearchRepository;
        private final AdvertPricesRepository advertPricesRepository;
        private final AdvertFacilityRepository advertFacilityRepository;
        private final AdvertVirtualPackagesRepository advertVirtualPackagesRepository;
        private final BookingRepository bookingRepository;
        private final AdvertMediasRepository advertMediasRepository;
        private final MediaRepository mediaRepository;
        private final AmazonS3Service amazonS3Service;
        private final OfficeBuildingSecurityRepository officeBuildingSecurityRepository;
        private final OfficeCyberSecurityRepository officeCyberSecurityRepository;
        private final OfficeFacilityRepository officeFacilityRepository;
        private final OfficeMediasRepository officeMediasRepository;
        private final OfficeNotificationsRepository officeNotificationsRepository;
        private final OfficePropertiesRepository officePropertiesRepository;
        private final OfficeRoomsRepository officeRoomsRepository;
        private final OfficeViewsRepository officeViewsRepository;
        private final OwnerCompanyRepository ownerCompanyRepository;
        private final PushNotificationTokenRepository pushNotificationTokenRepository;
... and so many other repositories and 


//CONSTRUCTOR etc.

程序中的所有内容都与用户相关,如果我删除用户,那么一切都会消失。 我不确定它是正确的样式或流程,如果单体应用程序中有任何其他选项,我该如何使用更好的方法来做到这一点? 我是否必须将所有相关的存储库接口注入到当前服务中?

注意:我没有使用任何队列服务,如 Kafka、Sqs、RabbitMq 等。

这并不重要,你的架构是什么,单体还是微服务 - 模式保持不变。

基本思想:将大型删除操作分解为单独的步骤,例如:

public interface DeleteStep<E> {

    void delete(E entity);

}

@Component
public class DeleteFiles implements DeleteStep<User> {

    @Autowired
    AmazonS3Service amazonS3Service

    @Override
    public void delete(User user) {
         amazonS3Service.deleteUserFiles(user);
    }

}


@Component
public class DeleteNotifications implements DeleteStep<User> {

    @Autowired
    OfficeNotificationsRepository officeNotificationsRepository;

    @Override
    public void delete(DmUser user) {
        officeNotificationsRepository.deleteUserNotifications(user);
    }

}

现在我们DeletionService的主体看起来像:

@Autowired
ObjectProvider<DeleteStep<User>> userDeletionSteps;

public void deleteUser(User user) {
    userDeletionSteps.forEach(s -> s.delete(user));
}

现在我们实际上可以通过利用应用程序事件来改进这个基本思想,例如:

public class UserDeleteEvent {

    private final User user;

    public UserDeleteEvent(User user) {
        this.user = user;
    }

    public User getUser() {
        return user;
    }
    
}


interface OfficeNotificationsRepository extends ... {

    @EventListener(UserDeleteEvent.class)
    default void onUserDeleted(UserDeleteEvent event) {
        deleteUserNotifications(event.getUser());
    }

}

class AmazonS3Service ... {

    @EventListener(UserDeleteEvent.class)
    void onUserDeleted(UserDeleteEvent event) {
        deteteUserFiles(event.getUser());
    }

}

现在我们的DeletionService变成了:

@Autowired
ApplicationEventPublisher eventPublisher;

public void deleteUser(User user) {
    eventPublisher.publishEvent(new UserDeleteEvent(user));
}

此外,我们可以利用@DomainEvents并摆脱DeletionService - UserRepository可以调度应用程序事件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM