Как правильно внедрить много служб в контроллер Spring MVC? - PullRequest
0 голосов
/ 10 января 2019

Я создал приложение Spring MVC, которое имеет 3 пользовательских типа. Я создал отдельные контроллеры для каждого из них. Теперь в каждом из них я должен ввести классы обслуживания, поэтому я сделал это так:

@Controller
@RequestMapping("teacher")
public class TeacherController {

@Autowired
private StudentService studentService;

@Autowired
private GradeService gradeService;

@Autowired
private SubjectService subjectService;

@Autowired
private StudentGroupService studentGroupService;

@Autowired
private NewsService newsService;

@GetMapping("/index")
public String indexPage(Model theModel) {
    List<News> tempNewsList = newsService.getNews();

    theModel.addAttribute("theNewList", tempNewsList);

    return "teacher/index";
}

Этот код использует инъекцию поля. Который, как я теперь узнал, является решением, которого следует избегать и заменять инжектором конструктора. Итак, я автоматически связал конструктор со всеми этими полями, например:

@Autowired
public TeacherController(StudentService studentService, GradeService gradeService, SubjectService subjectService, StudentGroupService studentGroupService, NewsService newsService) {
    this.studentService = studentService;
    this.gradeService = gradeService;
    this.subjectService = subjectService;
    this.studentGroupService = studentGroupService;
    this.newsService = newsService;
}

Это хорошее решение, создавая такой подробный конструктор в таком простом коде? А что если бы в моем коде было еще больше сервисов? Это даже приемлемо, или в этом случае я должен рефакторинг своего кода, например делегировать сервисы другим сервисам или создать больше контроллеров?

Ответы [ 2 ]

0 голосов
/ 10 января 2019

В заключение, согласно документации, если существует много DI, вы можете оценить каждый и попытаться использовать набор на основе и / или на основе конструктора. Еплайн документации, который использовать ниже:

DI на основе конструктора или сеттера?

Поскольку вы можете смешивать DI на основе конструктора и сеттера, рекомендуется использовать конструкторы для обязательных зависимостей, а также методы установки или методы настройки для необязательных зависимостей. Обратите внимание, что использование аннотации @Required в методе сеттера может использоваться для того, чтобы свойство стало обязательной зависимостью.

Команда Spring, как правило, поддерживает внедрение конструктора, поскольку оно позволяет реализовывать компоненты приложения как неизменяемые объекты и гарантирует, что требуемые зависимости не равны NULL. Более того, внедренные конструктором компоненты всегда возвращаются клиентскому (вызывающему) коду в полностью инициализированном состоянии. В качестве примечания следует отметить, что большое количество аргументов конструктора является неприятным запахом кода, подразумевая, что класс, вероятно, имеет слишком много обязанностей и должен быть реорганизован для лучшего решения правильного разделения проблем.

Внедрение сеттера должно в первую очередь использоваться только для необязательных зависимостей, которым могут быть назначены разумные значения по умолчанию в классе. В противном случае проверки не-null должны выполняться везде, где код использует зависимость. Одним из преимуществ внедрения сеттера является то, что методы установки делают объекты этого класса пригодными для реконфигурации или повторного внедрения позже. Таким образом, управление через JMX MBeans является убедительным примером использования для инъекции сеттера.

Используйте стиль DI, который наиболее подходит для определенного класса. Иногда, когда вы имеете дело со сторонними классами, для которых у вас нет исходного кода, выбор делается за вас. Например, если сторонний класс не предоставляет каких-либо методов-установщиков, тогда внедрение конструктора может быть единственной доступной формой DI.

0 голосов
/ 10 января 2019

Вы сами на это хорошо ответили! Spring решает именно эту проблему в документах здесь в поле с заголовком DI на основе конструктора или сеттера? :

Команда Spring обычно выступает за инжекцию конструктора, так как это позволяет вы реализуете компоненты приложения как неизменяемые объекты и обеспечивает что требуемые зависимости не равны нулю. Более того, Внедренные конструктором компоненты всегда возвращаются клиенту (вызывающий) код в полностью инициализированном состоянии. Как примечание, большой количество аргументов конструктора является неприятным запахом кода, подразумевая, что класс, вероятно, имеет слишком много обязанностей и должен быть реорганизован в лучше обратиться к правильному разделению проблем.

То есть в идеале вы должны рефакторинг. Использовал SOLID принципы и подумал: «Какую единственную работу в классе я создаю?».

...