✅ 지금까지의 빌드업 정리
#️⃣ 설정값
pom.xml (**키워드: dependency) |
maven설정(빌드역할) | tomcat, mybatis, jstl, spring dependency 꽂기 (maven project생성 후 필요한것 꽂기) |
web.xml (**키워드: mapping) |
(webapp - WEB-INF 내부) 톰캣설정 |
외부에서 접근하는 url 패턴 & app 이름 mapping (프로젝트-buildPath에 서버환경 만들어주고 web.xml설정) |
여기 있는 app 이름을 기반으로 나중에 app-servlet.xml을 만들어준다 (app-servlet.xml은 dispatcher servlet의 지시서역할이며 스프링 MVC 도입 이후에는 스프링의 지시서인 config.xml가 된다) |
||
config.xml (**키워드 : bean) |
(webapp - WEB-INF 내부) 스프링설정 |
url과 컨트롤러( 혹은 dao) bean 조립 (annotation으로도 설정가능) |
ClassPathXmlApplicationContext나 AnnotationConfigApplicationContext로 xml 읽어들이기 |
#️⃣ 홈디렉토리
webapp -- 홈디렉토리
ㄴ WEB-INF -- 클라이언트로부터 jsp를 숨기는 곳. jsp를 컨트롤러와 소통할 수 있도록 한다
------------------ 이 단계에서 @WebServlet("url")로 경로를 연결하지 않는다. controller와 jsp 둘만을 연결시킴!
#️⃣ 서블릿 역할의 발전 ▶ 스프링 MVC의 도입
서블릿역할: dispatcher 를 가지고 jsp에게 forwarding해주기
▶ 컨트롤러를 다시 프론트 컨트롤러(라우터역할의 dispatcher servlet)와 POJO컨트롤러로 나누기
▶ 프론트 컨트롤러 형태가 비슷해서 라이브러리가 제공됨 == 스프링 mvc
POJO 컨트롤러 : MVC의 MV만 가지고 있음.
public class ListController implements Controller{
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception{
return mv;}
}
#️⃣ 스프링 MVC 도입
: 프론트 컨트롤러의 역할이 비슷하므로 도입된 스프링 MVC
- 서비스+다오를 합쳐서 내가 원하는 객체를 만들어줘
- 객체를 저장해서 가지고 있다가 내가 원할떄 넘겨줘 (IoC가 곧 DI)
✅ annotation으로 설정하기
xml을 쓰지 않는 대신 자바클래스에 설정코드를 만들어준다 (업무로직 코드가 아님)
annotation을 붙일때는 1. 클래스에 붙여서 해당 클래스 자체를 인식시킬수도 있고 (@Component) 2. 메서드에 붙여서 해당 메서드를 인식시킬 수도 있다.(@Autowired)
#️⃣ 객체 생성법
- @Bean으로 해당 객체 생성하기 (이름필요없음. 어떤 객체를 new할지 지정 가능)
- @ComponentScan으로 해당 패키지 스캔해서 객체 생성하기
//방법2. 패키지 내부의 컴포넌트를 스캔하도록 만들기
@ComponentScan("com.newlecture.spring")
public class SpringConfig {
//방법1. Bean으로 해당 객체 생성하기 -- 이름 따로 지정할 필요 없음
// @Bean
// public MenuDao dao() {
// return new Dm2MenuDao();
// }
}
👉 스캔하는 범위가 넓어지면 성능이 떨어질 수 있으므로 디테일하게 설정해주는게 좋다. 이를 위해 패키지를 여러개 만들게 된다면 배열을 통해 여러 페이지를 설정할 수 있다. (@ComponentsScans("패키지주소"))
👉 보통은 기본패키지를 설정해서 뒤지게 한다 (service, dao등은 기본패키지 이름 하위로 붙으므로 한번에 찾게 됨)
#️⃣ 객체 생성뒤 Dao와 연결하는 @Autowired (== setter injection)
@Autowired
: 객체와 setter를 연결하는 방법
@Component를 뒤져서 그 안에있는 @Autowired의 setter와 조립해준다.
👉 constructor나 setter에 붙여놓으면 초기화를 함께 진행할 수 있다 (constructor나 setter가 품고있는 프로시져를 함께 실행함)
오류발생 - The virtual machine was unable to remove all stack frames running old code from the call stack.
메인함수 내에서 스프링 연결을 이것저것 교차해서 연결해보다가 난 오류...
#️⃣ 이클립스에서 저장할때 뜨는 오류 - The virtual machine was unable to remove all stack frames running old code from the call stack. "가상 머신은 호출 스택에서 이전 코드를 실행하는 모든 스택 프레임을 제거하지 못했습니다." 이 오류 메시지는 Java 또는 기타 가상 머신에서 실행되는 프로그램에서 발생하는 것으로, 프로그램의 함수 호출을 추적하는 호출 스택(call stack)을 관리하는 데 문제가 있음을 나타냅니다. 이 오류가 발생하는 일반적인 이유와 해결 방법은 다음과 같습니다:
|
#️⃣ 생성자에 주입하기 (==constructor injection)
: 생성하면서 초기화 할 일이 있을때 사용
@Autowired //--constructor injection
public MenuServiceImp(MenuDao dao) {
System.out.println("constructor");
this.dao = dao;
}
#️⃣ 필드에 연결하기 (==field injection)
: 필드에 있는 자료형명의 이름은 아무 의미가없음. 따라서 캡슐이 깨지진않으며 private도 @autowired도 설정할 수 있다.
//어노테이션을 가지고 클래스 자체에 설정을 붙인다.
@Component()
public class MenuServiceImp implements MenuService {
// private DmMenuDao dao;
@Autowired // --field injection
private MenuDao dao;
//안에서 생성을 하지않고 생성된 객체 자체를 꽂도록 하기
public MenuServiceImp() {
// dao = new Dm2MenuDao();
}
// @Autowired //--constructor injection
public MenuServiceImp(MenuDao dao) {
this.dao = dao;
}
// @Autowired //--setter Injection
public void setDao(MenuDao dao) {
this.dao = dao;
}
@Override
public List<Menu> getList() {
return dao.findAll();
}
}
#️⃣ @Component 세분화하기
👉 MVC는 controller, service, dao로 계층이 나누어져있는데 그에 맞게 component를 설정해주는게 좋음
✅ XML과 annotation을 섞어서 설정하기
👉 기본은 xml이고 annotation을 얹어서 쓴다. XML과 annotation 각각이 어느범위까지 커버하는지를 체크하는것이 관건.
#️⃣ 1. @Component는 xml로 읽고 객체 내에 있는 annotation만 읽도록 설정하기
👉 config.xml에 context 설정(annotation을 읽겠다는 설정)을 넣어준다.
#️⃣ 2. @Component와 @Autowired의 등 annotation을 모두 읽겠다는 설정을 xml에 하고 싶다면? (config.xml은 읽히는 상태)
#️⃣ annotation을 붙일 수 없는 상황은? -- xml을 활용한다
우리가 만든 코드는 소스코드가 있어서 annotation을 붙일 수 있지만 타인이 만든, 보따리에 이미 들어가있는 소스코드는 annotation을 붙일 수 없다.
//소스코드가 없는 놈을 한보따리에 담아달라고 해야함
//@Component
@Configuration // -- Bean 전용 component
public class BeanConfig {
//list라는 이름으로 해당 객체를 담아달라. -- 이럴땐 함수로 동작하는게 아니며 함수 명이 담을 이름이 된다.
@Bean
public List list() {
return new ArrayList();
}
}
✅ 프로젝트의 app-servlet.xml(==config.xml) 에 설정한 url-controller 구조를 annotation으로 변경하기
: url당 클래스를 맵핑하면 클래스가 그만큼 만들어짐 (url이 100개면 클래스가 100개가 됨)
👉 따라서 annotation을 사용해서 클래스단위가 아닌 함수단위로 변경시키는게 좋음
#️⃣ 1. app-servlet.xml에서 context (혹은 mvc)추가
#️⃣ 2. 사용자 요청시 HomeController가 실행되도록 mapping하기
<!-- <bean id="/menu/list" class="kr.co.rland.web.controller.menu.ListController">
</bean> <bean id="/menu/detail" class="kr.co.rland.web.controller.menu.DetailController">
</bean> -->
(▲app-servlet.xml에서 설정하던 위 내용을 대신하는 컨트롤러를 만드는 것)
▼ mapping하는 방법을 알아보자
#️⃣ POJO 컨트롤러 없이 자체적으로 뷰 반환하는 법
👉 annotation이 함수에 붙는데 함수이름은 마음대로 해도 되고 여러 함수를 넣을 수도 있음
#️⃣ 경로별로 클래스 나누기
❓ 클래스는 언제 만들어야할까?
👉 경로에 해당하는건 모두 클래스로 만들어짐
예) root 경로는 HomeController 클래스/ menu에 해당하는건 메뉴클래스
package kr.co.rland.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller //-- 얘도 컨트롤러이므로 어노테이션 잊지말기
@RequestMapping("/menu") //상위 경로를 나눌 수 있음
public class MenuController {
@ResponseBody
@RequestMapping("/list")
public String menuList() { // --- 여기서 메서드 이름은 아무거나 넣어도 됨
return "list in the menu";
}
@ResponseBody
@RequestMapping("/detail")
public String menuDetail() {
return "detail in the menu";
}
}
#️⃣ 입력값 체크
//컨트롤러에서 jsp로 forwarding하기 (front controller아니고 POJO 임!)
@Controller
public class HomeController {
// @ResponseBody
@RequestMapping("/index")
public String index(String s) {
System.out.println(s);
//forwarding
return "/WEB-INF/view/index.jsp";
}
}
'😵 ~23.11.10' 카테고리의 다른 글
0918 | 스프링부트 / 부트에서 컨트롤러 설정하기 (0) | 2023.09.18 |
---|---|
0915 | SessionFactory 객체만들기 / spring mvc final (0) | 2023.09.18 |
0913 | DI, 스프링기능(IoC개념), XML과 Annotation을 활용한 지시서찾기 (0) | 2023.09.13 |
0912 | 컨트롤분리와 POJO / 스프링MVC / POJO 컨트롤러 만들기 (0) | 2023.09.13 |
0911 | MVC 모델 개념 / JSP action tag / JSTL / MVC모델2 (1) | 2023.09.11 |