스프링이 제공하는 컨트롤러는 애노테이션 시반으로 동작 -> 매우 유연하고 실용적
애노테이션을 사용한 컨트롤러
가장 우선순위가 높은 핸들러 배핑과 핸들러 어댑터
RequestMappingHandlerMapping 은 스프링 빈에서 @Controller가 클래스 레벨에 붙어있는 경우 매핑 정보로 인식됨.
@Controller // -> 이 어노테이션안에 @Componant애노테이션이 있어서 컴포넌트 스캔의 대상이 된다.
public class SpringMemberFromControllerV1 {
    @RequestMapping("/springmvc/v1/members/new-form")
    public ModelAndView process(){
        return new ModelAndView("new-form");
    }
}
스프링 3.0이하에서는 @requestMapping만 있어도 컨트롤러로 인식이 됬었는데 3.0이상부터는 @Controller가 없으면 컨트롤러로 인식되지않는다.
@RestController 는 @Controller를 포함하고 있기 때문에 인식이 됨.
@RequestMapping은 클래스 단위가 아닌 메서드 단위로 적용이 가능함 -> 통합이 가능하다.
v2버전 - 통합 버전
@Controller
@RequestMapping("/springmvc/v2/members")
public class SpringMemberControllerV2 {
    private MemberRepository memberRepository = MemberRepository.getInstance();
    @RequestMapping("/new-form")
    public ModelAndView form() {
        return new ModelAndView("new-form");
    }
    @RequestMapping("/save")
    public ModelAndView save(HttpServletRequest request, HttpServletResponse response){
        String username = request.getParameter("username");
        int age = Integer.parseInt(request.getParameter("age"));
        Member member = new Member(username, age);
        memberRepository.save(member);
        ModelAndView mv = new ModelAndView("save-result");
        mv.addObject("member",member);
        return mv;
    }
    @RequestMapping
    public ModelAndView list() {
        List<Member> members = memberRepository.findAll();
        ModelAndView mv = new ModelAndView("members");
        mv.addObject("members", members);
        return mv;
    }
}
v3버전 - > 실용적인 방식
@Controller
@RequestMapping("/springmvc/v3/members")
public class SpringMemberControllerV3 {
    private MemberRepository memberRepository = MemberRepository.getInstance();
    @GetMapping("/new-form")
    public String form() {
        return "new-form";
    }
    //파라미터를 직접 받을 수 있음
    //model을 전에 스프링mvc 직접생성시에 만들었을 때와 같은 model
    @PostMapping("/save")
    public String save(@RequestParam("username") String username,
                       @RequestParam("age") int age,
                       Model model) {
        Member member = new Member(username, age);
        memberRepository.save(member);
        model.addAttribute("member", member);
        return "save-result";
    }
    @GetMapping
    public String list(Model model) {
        List<Member> members = memberRepository.findAll();
        model.addAttribute("members", members);
        return "members";
    }
}