파게로그
[Spring MVC] Annotation을 활용한 서비스 객체 DI 등 본문
자바 애플리케이션의 초기화 또는 설정 파일은 XML 파일이나 Annotation이나 Java 설정 파일이나 property, yaml 등을 사용한다.
servlet-context.xml
<bean id="/emp" class="com.ddoongi.web.controller.EmpController">
<property name="empService" ref="empService" />
</bean>
위 스크립트에서 2라인을 Annotation으로 바꾸어보자.
그리고 위 파일에서 context namespace와 스키마 위치를 아래와 같이 추가한다.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
그리고 annotation을 통해서 config를 했기 때문에 반드시 이를 알려주어야 한다.
<context:annotation-config />
EmpController.java
public class EmpController implements Controller {
private EmpService empService;
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mv = new ModelAndView("/emp");
List<Emp> list = empService.getEmpList();
String name = list.get(2).getEname();
int empno = list.get(2).getEmpno();
Date hiredate = list.get(2).getHiredate();
mv.addObject("name", name);
mv.addObject("empno", empno);
mv.addObject("hiredate", hiredate);
return mv;
}
@Autowired
public void setEmpService(EmpService empService) {
this.empService = empService;
}
}
public class EmpController implements Controller {
@Autowired
private EmpService empService;
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mv = new ModelAndView("/emp");
List<Emp> list = empService.getEmpList();
String name = list.get(2).getEname();
int empno = list.get(2).getEmpno();
Date hiredate = list.get(2).getHiredate();
mv.addObject("name", name);
mv.addObject("empno", empno);
mv.addObject("hiredate", hiredate);
return mv;
}
public void setEmpService(EmpService empService) {
this.empService = empService;
}
}
@Autowired의 위치.. 이게 더 편하니까 조금 더 권장ㅇㅇ
다만 setter에다가 @Autowired를 달아두면 Autowired될 때 뭔가 수행할 수 있다.
한편 객체 생성을 위해서는 @Component 외에도
semantic한 annotation... @Controller, @Service, @Repository 등 사용 가능
이렇게 하면
<context:component-scan base-package="com.ddoongi.web.controller" /> 와 같이
패키지에서 어떤 컴포넌트를 생성할지 찾을 수 있도록 해주어야 한다.
컴포턴트 스캔 태그를 달았다면 <context:annotation-config /> 는 지워도 된다.
annotation으로 URL mapping하기
package com.ddoongi.web.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
public class IndexController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mv = new ModelAndView("index");
mv.addObject("myData", "이건 컨트롤러에서 모델에 박은거");
return mv;
}
}
원래 이랬던 컨트롤러는...
아래와 같이 쓸 수 있다.
package com.ddoongi.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller // 객체화하는 역할. 더 이상 implements Controller가 필요하지 않음
public class IndexController {
@RequestMapping("/index")
public void foo() {
}
// 더 이상 필요하지 않다.
// @Override
// public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
// ModelAndView mv = new ModelAndView("index");
// mv.addObject("myData", "이건 컨트롤러에서 모델에 박은거");
// return mv;
// }
}
다만 @RequestMapping이 작동하기 위해서 servlet-context.xml에
<mvc:annotation-driver /> 태그를 삽입해주어야한다.
다만 Controller로서 역할을 다하기 위해서......
일단 특징을 생각해보면, 이제 URL에 mapping되는 것은 클래스가 아니라 함수이다.
그러면 이제 Controller는 함수일 것이고... 클래스는 Controller를 담는 컨테이너 역할을 한다..
그럼 더이상 IndexController가 아니라, 루트에 존재하는 폴더 같은 거니까..
HomeController라고 쓴다.
IndexController.java HomeController.java
package com.ddoongi.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HomeController {
@RequestMapping("/index")
public String index() {
return "index"; // View 정보를 반환
}
@RequestMapping("/help")
public String help() {
return "help"; // View 정보를 반환
}
// 더 이상 필요하지 않다.
// @Override
// public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
// ModelAndView mv = new ModelAndView("index");
// mv.addObject("myData", "이건 컨트롤러에서 모델에 박은거");
// return mv;
// }
}
근데 URL마다 다 메서드를 만들면 너무 많겠지?
emp에 관련된건 당연히 빼면 좋긴 하겠다.
이 물리 architecture를 나누다보면 느끼는 어려움이... 여기서 아마 RESTful API가 나오는게 아닐까 생각이 든다.
(가능하면 파일구조랑 URL구조를 같이하면좋다)
패키지 내 패키지 내 Controller(클래스) 내 메서드가 하나의 URL이 될 것
'콤퓨타 왕기초 > Spring' 카테고리의 다른 글
@RestController와 한글 깨짐 (0) | 2021.05.02 |
---|---|
[Spring MVC] 문서 출력 방법 (0) | 2021.05.02 |
[Spring MVC] Spring 설정 파일 분리하기 (0) | 2021.05.01 |
[Spring MVC] 서비스 객체, Connection 분리하기 (0) | 2021.05.01 |
[Spring MVC] 서비스 객체 사용하기 (0) | 2021.05.01 |