Проблем с извикване на хранилища от Spring MVC контролери

Имам Spring MVC приложение с хранилища (@Repository), инжектирани директно в някои контролери (@Controller), като по този начин понякога заобикалям слоя услуга.

Например: имам няколко findByXXX метода в моите хранилища и не намерих начин за автоматично генериране на обвиващи методи около персонализирани методи в моите услуги с помощта на Spring Roo.

Ето защо имам дилема: или да заобиколя Сервизния слой (лошо), или да прекарам много време (лошо) в създаване на прости методи за обвивка в Сервизния слой около персонализираните ми методи на хранилище.

Някой има ли решение на тази дилема?

Редактиране 1: Ето един от моите контролери, поискан от @Nabil:

@Controller
@RequestMapping("/signup")
public class SignupController {

    @Autowired
    private SignupService signupService;

    @Autowired
    private SigninService signinService;

    @Autowired
    private MemberRepository memberRepository;

    @Autowired
    private PreferenceService preferenceService;

    @RequestMapping(method = RequestMethod.GET, produces = "text/html")
    public String signupForm(@ModelAttribute SignupInfo signupInfo, Model model) {
        populateForm(model, signupInfo);
        return "signup";
    }

    @RequestMapping(method = RequestMethod.POST, produces = "text/html")
    public String signup(@ModelAttribute @Validated({ Validation.Signup.class }) SignupInfo signupInfo, BindingResult bindingResult, Model model) {
        if (!preferenceService.isEmailAvailable(signupInfo.getMember().getEmail())) {
            bindingResult.rejectValue("member.email", "controller.signup.email_already_used");
        }

        if (bindingResult.hasErrors()) {
            populateForm(model, signupInfo);
            return "signup";
        }

        signupService.signupMember(signupInfo.getMember(), signupInfo.getAddressReference());
        signinService.signin(memberRepository.findByEmail(signupInfo.getMember().getEmail()));
        return "redirect:preference/email";
    }

    private void populateForm(Model model, SignupInfo signupInfo) {
        model.addAttribute("signupInfo", signupInfo);
        model.addAttribute("roles", Arrays.asList(Role.ROLE_BASIC_CHILDMINDER, Role.ROLE_BASIC_FAMILY));
    }
}

person balteo    schedule 10.09.2013    source източник
comment
Можете ли да изпратите пример за един от вашите методи на контролер   -  person Nabil    schedule 10.09.2013


Отговори (1)


Решението би било да поставите цялата си бизнес логика в услуги. Отговорността на контролера трябва да бъде единствено да преобразува HTTP заявката в единично извикване на услуга и след това да преведе резултата или изключението в HTTP отговор. Услугата трябва да извика всички хранилища и други услуги, необходими за извършване на бизнес операцията.

Що се отнася до няколко findByXXX, делегирането не е лошо нещо. Въпреки това бих избрал универсален единичен метод findAll(Predicate p) в слоя хранилище. т.е. като JPA документи на Spring Data предложете или дори по-добре използвайте QueryDSL. Тогава сервизният слой ще конструира предиката, вместо просто да делегира на по-нисък слой.

person Roadrunner    schedule 10.09.2013