spring 如何使@Service被“新”操作员调用?

wfsdck30  于 2022-10-30  发布在  Spring
关注(0)|答案(1)|浏览(147)

我正在使用java spring创建一个电子日记应用程序,但是我遇到了一个小问题。我决定创建一个带有状态模式的角色系统。所以这个系统的逻辑应该看起来像这样:
1.在控制器中,接受请求后,创建context类的对象,context类的构造器根据用户角色得到具体的RoleClass(使用工厂)
1.在控制器中,我们调用要执行的上下文的方法
1.在上下文中,我们调用希望执行的角色的方法。
1.在角色类中,我们调用要执行的服务的方法。
但是这里我遇到了一个问题。我有一个上下文类,它创建了一个UserService类的对象,其中包含了很多**@Autowired字段。所以我决定给上下文类添加@Service注解,并在UserContext类的构造函数上添加了@Autowired注解。
但是Spring会在编译阶段自动连接所有字段,所以当我启动程序时,SecurityContextHolder中不会有任何
UserPrincipal**。所以这里我需要在请求阶段,在控制器中创建一个UserContext类的对象。这就是为什么我在UserContext类中添加了@Configurable注解。但是当UserContext类创建时,UserService的自动连接字段由空值填充。
那么,什么会成为问题呢?
顺便说一句,我认为最好创建一个UserService类的构造函数,它将接受所有的参数(如UserRepository),但这里有另一个问题:
1.我在其他类中经常使用UserService类。例如,我有一个模型,在那里我调用了这个类。在这里,在创建了类的这个对象后,字段将自动连接。

@Getter @Setter
public class ClassGetModel {

    private long id;

    private int number;

    private char letter;

    private SchoolGetModel school;

    private List<UserGetModel> students;

    public static ClassGetModel toModel(ClassEntity schoolClass) {
        ClassGetModel model = new ClassGetModel();
        ModelMapper mapper = new ModelMapper();
        mapper.getConfiguration().setSkipNullEnabled(true);
        mapper.map(schoolClass, model);
        model.setSchool(SchoolGetModel.toModel(schoolClass.getSchool()));
        UserService userService = new UserService();
        model.setStudents(userService.convertToUserGetModelList(schoolClass.getStudents()));
        return model;
    }
}

还有一个问题是构造函数的参数数量。如果我的服务有很多字段,而这些字段在我的程序中使用,我就必须把它们都给这个构造函数,即使在RoleFactory中。
下面是我的代码:用户控制器

@RestController
@RequestMapping("/api/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private UserContext userContext;

    @GetMapping("/marks")
    public ResponseEntity<Object> getMarks() {
        try {
            return ResponseEntity.ok(userContext.getMarks());
        } catch (Exception e) {
            return new ResponseEntity<>(e.getMessage(), HttpStatus.NOT_FOUND);
        }
    }

用户上下文

@Service @Configurable @Scope("prototype")
public class UserContext {

   @Autowired
    public UserContext(UserService userService) {
        this.userService = userService;
    }
    public List<HomeworkGetModel> getHomework() throws UserNotFoundException {
        UserRole userRole = RoleFactory.getUserRole(userService.getCurrentUser().getRole().getName());
        return userRole.getHomework();
    }

    public List<MarkGetModel> getMarks() throws UserNotFoundException {
        UserRole userRole = RoleFactory.getUserRole(userService.getCurrentUser().getRole().getName());
        return userRole.getMarks();
    }
}

用户角色

public interface UserRole {
    default UserGetModel getUser(long id) throws UserNotFoundException {
        throw new NotImplementedException();
    }

    default List<UserGetModel> getAllUsers() {
        throw new NotImplementedException();
    }

    default UserEntity updateUser(UserUpdateModel newUserData) throws UserNotFoundException {
        throw new NotImplementedException();
    }

    default UserEntity deleteUser() throws UserNotFoundException {
        throw new NotImplementedException();
    }

    default List<MarkGetModel> getMarks() throws UserNotFoundException {
        throw new NotImplementedException();
    }

    default List<MarkGetModel> getMarksByDate(String date) throws UserNotFoundException, ParseException {
        throw new NotImplementedException();
    }

    default List<MarkGetModel> getMarksBySubject(String subjectName) throws UserNotFoundException {
        throw new NotImplementedException();
    }

    default List<MarkGetModel> getMarksByDateAndSubject(DateAndSubjectModel dateAndSubject) throws UserNotFoundException, ParseException {
        throw new NotImplementedException();
    }

    default SubjectGetModel getSubject(long id) throws SubjectNotFoundException {
        throw new NotImplementedException();
    }

    default SubjectGetModel getSubject(String name) throws SubjectNotFoundException {
        throw new NotImplementedException();
    }

    default SchoolGetModel getSchoolById(long schoolId) throws SchoolNotFoundException {
        throw new NotImplementedException();
    }

    default SchoolGetModel getSchoolByNumber(int schoolNumber) throws SchoolNotFoundException {
        throw new NotImplementedException();
    }

    default List<SchoolGetModel> getSchools() {
        throw new NotImplementedException();
    }

    default ClassGetModel getSchoolClass(ClassGetByNumberModel classData) throws com.diary.diary.exception.school_class.ClassNotFoundException, SchoolNotFoundException {
        throw new NotImplementedException();
    }

    default List<ClassGetModel> getClasses() {
        throw new NotImplementedException();
    }

    default List<HomeworkGetModel> getHomework() throws UserNotFoundException {
        throw new NotImplementedException();
    }

    default List<HomeworkGetModel> getHomeworkByDate(String date) throws UserNotFoundException, ParseException {
        throw new NotImplementedException();
    }

    default List<HomeworkGetModel> getHomeworkBySubject(String subjectName) {
        throw new NotImplementedException();
    }

    default ClassEntity addClass(ClassAddModel classData) {
        throw new NotImplementedException();
    }

    default ClassEntity addUserToClass(AdminAddUserToClassModel userAndClassModel) {
        throw new NotImplementedException();
    }

    default ClassEntity deleteClass(long id) {
        throw new NotImplementedException();
    }

    default UserEntity removeUserFromClass(AdminRemoveUserFromClassModel userClassModel) {
        throw new NotImplementedException();
    }

    default SchoolEntity addSchool(SchoolAddModel schoolData) {
        throw new NotImplementedException();
    }

    default SchoolEntity deleteSchool(long id) {
        throw new NotImplementedException();
    }

    default UserEntity removeUserFromSchool(AdminRemoveUserFromSchoolModel userSchoolModel) {
        throw new NotImplementedException();
    }

    default SubjectEntity addSubject(SubjectAddModel subjectData) {
        throw new NotImplementedException();
    }

    default SubjectEntity updateSubject(SubjectUpdateModel newSubjectModel) {
        throw new NotImplementedException();
    }

    default SubjectEntity deleteSubject(SubjectDeleteModel subjectDeleteData) {
        throw new NotImplementedException();
    }

    default TimetableEntity addTimetable(TimetableAddModel timetableData) {
        throw new NotImplementedException();
    }

    default TimetableEntity updateTimetable(TimeTableUpdateModel newTimetableData) {
        throw new NotImplementedException();
    }

    default TimetableEntity deleteTimetable(long id) {
        throw new NotImplementedException();
    }

    default ClassEntity addTimetableToClass(TimetableClassModel timetableClass) {
        throw new NotImplementedException();
    }

    default ClassEntity deleteTimetableFromClass(long classId) {
        throw new NotImplementedException();
    }
}

用户服务

@Service @Configurable @Scope("prototype")
public class UserService implements UserDetailsService {

    @Autowired
    private UserRepository userRepo;
    @Autowired
    private RoleRepository roleRepo;

    @Autowired
    private MarkMethods markMethods;

    private final BCryptPasswordEncoder bCryptPasswordEncoder
            = new BCryptPasswordEncoder();

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserEntity user = userRepo.findByLogin(username);
        if(user == null) {
            throw new UsernameNotFoundException("user with such login not found");
        }
        SimpleGrantedAuthority userRole = new SimpleGrantedAuthority(user.getRole().toString());
        return new User(Long.toString(user.getId()), user.getPassword(), List.of(userRole));
    }

    public UserGetModel getUser(long userID) throws UserNotFoundException {
        UserEntity user = userRepo.findById(userID)
                .orElseThrow(() -> new UserNotFoundException("no user with such id"));
        return convertUserToGetModel(user);
    }

    public UserEntity getCurrentUser() throws UserNotFoundException {
        Authentication authentication = SecurityContextHolder
                .getContext().getAuthentication();
        if(authentication == null) {
            return null;
        }
        Long userId = Long.valueOf((String) authentication.getPrincipal());
        return userRepo.findById(userId)
                .orElseThrow(() -> new UserNotFoundException("current user wasn't found"));
    }

    public List<MarkGetModel> getMarks() throws UserNotFoundException {
        checkUserRoleOrThrow(RoleNames.ADMIN, getCurrentUser());
        UserEntity student = getCurrentUser();
        return convertToMarkGetModelList(student.getMarks());
    }

如果你知道如何解决这个问题,请告诉我,我将不胜感激!

zlhcx6iw

zlhcx6iw1#

您可以做的是用@Scope注解UserService类,并将作用域设置为请求作用域(请参见此处https://www.baeldung.com/spring-bean-scopes)。
现在,无论何时请求bean,都将获得一个完整的新示例(此时安全上下文已设置)。
因此TLDR:
1.通常将UserService作为bean注入控制器。
1.如上所述,使用@Scope注解UserService

相关问题