> 다시 한번 정리하고 넘어가자
- 프로젝트 우클릭 - Maven - Update Project
- 패키지 우클릭 - New - Spring Bean Configuration File
- 클래스 우클릭 Run As Java Application 으로 실행하기
lecture.p06core
MyDao
package lecture.p06core;
public class MyDao {
}
MyServlet
package lecture.p06core;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public class MyServlet {
private MyDao myDao;
// public MyServlet(MyDao myDao) {
// this.myDao = myDao;
// }
}
@setter 작성하여 setMyDao 메소드를 통해 주입할 수도 있지만,
아래 주석처리한 것처럼 생성자를 이용해서 주입할 수도 있다!
이를 직접 작성하지 않고 annotation 을 작성할거임 - @AllArgsConstructor
(@getter 는 읽기를 위해 작성)
context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="myServlet" class="lecture.p06core.MyServlet">
<constructor-arg ref="myDao"></constructor-arg>
</bean>
<bean id="myDao" class="lecture.p06core.MyDao"></bean>
</beans>
이번에는 property 태그가 아닌 constructor-arg 태그 작성 (생성자를 이용해 주입하는 태그)
App
package lecture.p06core;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import lombok.extern.log4j.Log4j;
@Log4j
public class App {
public static void main(String[] args) {
String config = "lecture/p06core/context.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(config);
MyServlet myServlet = context.getBean(MyServlet.class);
MyDao myDao = context.getBean(MyDao.class);
log.warn(myServlet);
log.warn(myDao);
log.warn(myServlet.getMyDao());
}
}
결과
lecture.p07core
context.xml
패키지 우클릭 - New - Spring Bean Configuration File 에서 name 작성 후 바로 finish 하지말고 next
위와 같은 ★옵션에서 beans, context 체크하여 생성★하기
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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 http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<bean id="myServlet" class="lecture.p07core.MyServlet"></bean>
<bean id="myDao" class="lecture.p07core.MyDao"></bean>
</beans>
* MyServlet, MyDao 는 생성만 하고 아무것도 작성하지 않음
App
package lecture.p07core;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import lombok.extern.log4j.Log4j;
@Log4j
public class App {
public static void main(String[] args) {
String config = "lecture/p07core/context.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(config);
MyServlet myServlet = context.getBean(MyServlet.class);
MyDao myDao = context.getBean(MyDao.class);
log.warn(myServlet);
log.warn(myDao);
}
}
> 다른 방법
context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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 http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:component-scan base-package="lecture.p07core"></context:component-scan>
</beans>
<context:component-scan base-package="lecture.p07core"></context:component-scan>
와 같이 context:component-scan 태그 작성하고
MyServlet
package lecture.p07core;
import org.springframework.stereotype.Component;
@Component
public class MyServlet {
}
MyDao
package lecture.p07core;
import org.springframework.stereotype.Component;
@Component
public class MyDao {
}
위와 같이 MyServlet, MyDao 에 annotation 으로 @Component 작성 (bean 을 생성할 수 있도록 함)
lecture.p08coreExercise
연습
Student
package lecture.p08coreExercise;
import org.springframework.stereotype.Component;
@Component
public class Student {
}
Teacher
package lecture.p08coreExercise;
import org.springframework.stereotype.Component;
@Component
public class Teacher {
}
context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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 http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:component-scan base-package="lecture.p08coreExercise"></context:component-scan>
</beans>
App
package lecture.p08coreExercise;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import lombok.extern.log4j.Log4j;
@Log4j
public class App {
public static void main(String[] args) {
String config = "lecture/p08coreExercise/context.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(config);
Student student = context.getBean(Student.class); // not exception
Teacher teacher = context.getBean(Teacher.class); // not exception
log.warn(student);
log.warn(teacher);
log.warn("--- bean 이름으로 얻기 ----");
log.warn(context.getBean("student"));
log.warn(context.getBean("teacher"));
}
}
bean 이름으로 얻기 아래에 context.getBean 까지는 알겠는데 그냥 냅다 "student" "teacher" 넣는다고?
- bean 이름은 클래스 이름 (소문자로 바꾼) 으로 생성된다. 그래서 student, teacher 이 bean 이름인 것.
lecture.p09core
context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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 http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:component-scan base-package="lecture.p09core"></context:component-scan>
</beans>
MyDao
package lecture.p09core;
import org.springframework.stereotype.Component;
@Component
public class MyDao {
}
MyServlet
package lecture.p09core;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MyServlet {
private MyDao myDao;
public MyDao getMyDao() {
return myDao;
}
@Autowired
public void setMyDao(MyDao myDao) {
this.myDao = myDao;
}
}
set/get 메소드 직접 작성했는데, 그냥 @Getter, @Setter 작성해도됨
@Autowired : 주입되도록 하는 역할 (set 메소드 위에 작성됨)
Dao → Servlet
App
package lecture.p09core;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) {
String config = "lecture/p09core/context.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(config);
MyServlet myServlet = context.getBean(MyServlet.class);
MyDao myDao = context.getBean(MyDao.class);
System.out.println(myServlet);
System.out.println(myDao);
System.out.println(myServlet.getMyDao());
}
}
lecture.p10coreExercise
context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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 http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:component-scan base-package="lecture.p10coreExercise"></context:component-scan>
</beans>
Memory
package lecture.p10coreExercise;
import org.springframework.stereotype.Component;
@Component
public class Memory {
}
Computer
package lecture.p10coreExercise;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import lombok.Getter;
import lombok.Setter;
@Component
@Getter
@Setter(onMethod_ = @Autowired)
public class Computer {
private Memory memory;
// @Autowired
// public void setMemory(Memory memory) {
// this.memory = memory;
// }
//
// public Memory getMemory() {
// return memory;
// }
}
@Setter(onMethod_=@Autowired) 작성
App
package lecture.p10coreExercise;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) {
String config = "lecture/p10coreExercise/context.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(config);
System.out.println(context.getBean("computer")); // not null, not exception
System.out.println(context.getBean("memory")); // not null, not exception
System.out.println(context.getBean(Computer.class).getMemory()); // not null, not exception
}
}
lecture.p11core
context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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 http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:component-scan base-package="lecture.p11core"></context:component-scan>
</beans>
MyDao
package lecture.p11core;
import org.springframework.stereotype.Component;
@Component
public class MyDao {
}
MyServlet
package lecture.p11core;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import lombok.Getter;
@Component
@Getter
public class MyServlet {
private MyDao myDao;
@Autowired // 생성자가 하나만 존재할 경우 @Autowired가 없어도 DI 됨.
public MyServlet(MyDao myDao) {
this.myDao = myDao;
}
}
생성자를 이용하는 방법
App
package lecture.p11core;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) {
String path = "lecture/p11core/context.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(path);
MyServlet s = context.getBean(MyServlet.class);
MyDao d = context.getBean(MyDao.class);
System.out.println(s);
System.out.println(d);
System.out.println(s.getMyDao());
}
}
lecture.p12core
context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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 http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:component-scan base-package="lecture.p12core"></context:component-scan>
</beans>
MyDao
package lecture.p12core;
import org.springframework.stereotype.Component;
@Component
public class MyDao {
}
MyServlet
package lecture.p12core;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import lombok.Getter;
@Component
@Getter
public class MyServlet {
@Autowired
private MyDao myDao;
}
App
package lecture.p12core;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) {
String path = "lecture/p12core/context.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(path);
MyServlet s = context.getBean(MyServlet.class);
MyDao d = context.getBean(MyDao.class);
System.out.println(s);
System.out.println(d);
System.out.println(s.getMyDao());
}
}
> 정리
* 주입: DI (dependence injection)
1. <bean class=""></baen> 작성하여 bean 생성 (p04)
2. <bean class=""> <property name="" ref=""></property> </bean>
<bean id="" class=""></bean> 작성하여 주입 (p04, p05)
3. <bean id="" class=""><constructor-arg ref=""></constructor-arg></bean>
<bean id="" class=""></bean> 작성하고,
annotation @AllArgsConstructor 작성하여
생성자를 이용한 주입 (p06)
4. xml 파일 생성 시 옵션에서 beans, context 체크,
<context:component-scan base-package=""></context:component-scan> 작성하고,
annotation @Component 작성하여 bean 생성 (p07, p08)
5. 4번 + 주입하기 위해 set 메소드에 @Autowired 작성해줌 (p09, p10)
6. 4번 + 생성자를 이용해 주입하기위해 생성자에 @Autowired 작성해줌 (p11)
Tomcat 에서 Spring bean 을 만들고 DI 를 하기 위해서 Listener 를 사용!
(Listener 는 tomcat 이 시작하자마자 실행됨)
이러한 역할을 하는 listener 가 이미 spring 에 있다
WEB-INF > web.xml 파일
listener 태그가 존재
WEB-INF > spring > root-context.xml
어떤 bean 을 만들고 어떤 DI 를 하는지에 대한 설명을 root-context.xml 파일에 작성
Spring 에서 제공하는 servlet 도 있다 - DispatcherServlet
root-context.xml 은 listener 에, servlet-context.xml 은 servlet 에 사용됨
WEB-INF > spring > appServlet > servlet-context.xml
이 DispatcherServlet 을 언제 작동시킬지 경로를 작성 (이전에는 annotation 으로 작성했었음)
.xml 파일에서는 mapping 태그로 작성한다
/ 경로로 요청이 오면 appServlet 으로 전달 - 그러면 위의 DispatcherServlet 이 요청을 받음
이제 우리는 서블릿을 작성하지 않고, DispatcherServlet 이 모든 요청을 받아 처리하게 됨
DispatcherServlet 은 servlet-context.xml 설정파일을 읽어서 spring bean 을 만들고 DI 도 하게 됨
applicationContext 가 만들어진다 (리스너에서도, 서블릿에서도 만들어져 총 2개의 applicationContext)
(DispatcherServlet 에 요청이 오지 않아도 load-on-startup 태그에 의해 초기화 이루어짐)
ROOT 가 WEB 보다 상위, WEB 에서는 ROOT 참조 가능하지만 반대는 불가능
ROOT 내 bean 들에는 dao, service 같은 것들이 있다
> 참고
https://spring.io/projects/spring-framework
Learn 탭에서 최신버전의 Reference Doc. 과 API Doc. 참고
- Reference Doc. https://docs.spring.io/spring-framework/docs/current/reference/html/
주로 Core, Web Servlet 참고
특히 Web Servlet 의 1.1 DispatcherServlet, 1.3 Annotated Controllers
servlet-context.xml
WEB-INF > views 안에 .jsp 파일을 만들거고,
org.zerock.controller 패키지 안에 component 를 만들것임
p01controller
Controller01
그냥 class 로 생성하면된다
Spring MVC 에서 사용하는 @Controller annotation
https://docs.spring.io/spring-framework/docs/current/javadoc-api/ 참고
아무튼 @Component 대신 @Controller 씀
→ @Controller 가 붙은 클래스의 bean ! 이라고 이해하기
@RequestMapping 과 함께 쓰임
@RequestMapping("/cont01") : 경로 /cont01
package org.zerock.controller.p01controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/cont01")
public class Controller01 {
// "/cont01"
@RequestMapping("")
public void method00() {
System.out.println("메소드00 일함");
}
// "/cont01/met01"
@RequestMapping("/met01")
public void method01() {
System.out.println("메소드01 일함");
}
// "/cont01/met02" 요청이 왔을 때 일하는 메소드(method02)를 작성하세요. return : void
@RequestMapping("/met02")
public void method02() {
System.out.println("메소드02 일함");
}
// "/cont01/met03", "/cont01/met04" 로 요청이 왔을 때 일하는 메소드
@RequestMapping({"/met03", "/met04"})
public void method03() {
System.out.println("메소드 03 일함");
}
// "/cont01/met05", "/cont01/met06" 로 요청이 왔을 때 일하는 메소드 method05 작성
@RequestMapping({"/met05", "/met06"})
public void method05() {
System.out.println("메소드 05 일함");
}
}
annotation, 경로 주의깊게 보기
경로를 비워두거나 여러 경로를 하나에 작성할 수도 있다
("") : /cont01
("/") : /cont01/
({"/met03", "met04"}) : /cont01/met03 혹은 /cont01/met04
결과 ↓
프로젝트 run on server 로 실행 - 주소창에 경로 입력 /cont01/met01
이런 창이 뜨지만 무시하고 콘솔창 확인
Controller02
package org.zerock.controller.p01controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
@RequestMapping("/cont02")
public class Controller02 {
// url : "/cont02/met01" , method : get
@RequestMapping(value = "/met01", method = RequestMethod.GET)
public void method01() {
System.out.println("메소드 01 일함");
}
// url : "/cont02/met01" , method : post
@RequestMapping(value = "/met01", method = RequestMethod.POST)
public void method02() {
System.out.println("메소드 02 일함");
}
// @RequestMapping(value = "/met03", method = RequestMethod.GET)
@GetMapping("/met03")
public void method03() {
System.out.println("메소드 03 일함");
}
// url : "/cont02/met03", method : post 일하는 메소드 method04를 작성
// @RequestMapping(value = "/met03", method = RequestMethod.POST)
@PostMapping("/met03")
public void method04() {
System.out.println("메소드 04 일함");
}
@RequestMapping(value="/met05", method = {RequestMethod.GET, RequestMethod.POST})
public void mthod05() {
System.out.println("메소드 05 일함");
}
}
RequestMethod
https://docs.spring.io/spring-framework/docs/current/javadoc-api/ 참고
@RequestMapping(value = "/met01", method = RequestMethod.GET)
@RequestMapping(value = "/met01", method = RequestMethod.POST)
@GetMapping("/met03")
@PostMapping("/met03")
Get 방식의 요청은 Controller01 에서와 같이 해도 되지만 Post 방식은 터미널로 보내야 함 ↓
get 방식: curl -s 주소 > o.txt
post 방식: curl -s -X POST 주소 > o.txt
(주소는 프로젝트 실행하고 경로 입력한 것)
콘솔 창 결과 ↓
방식 get, post 두가지 설정 가능
method = {RequestMethod.GET, RequestMethod.POST}
Controller03
package org.zerock.controller.p01controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
@RequestMapping("/cont03")
public class Controller03 {
@RequestMapping("/met01")
public void method01(HttpServletRequest request) {
System.out.println("메소드 01 일함");
// 2. request 분석/ 가공
String name = request.getParameter("name");
String ageStr = request.getParameter("age");
int age = Integer.parseInt(ageStr);
// 3.
System.out.println(name);
System.out.println(age);
}
@RequestMapping("/met02")
public void method02(String name, Integer age) {
System.out.println("메소드 02 일함");
System.out.println(name);
System.out.println(age);
}
// /cont03/met03 : request 파라미터, address(String)와 id(Integer)를 받도록 메소드 작성
@RequestMapping("/met03")
public void method03(String address, Integer id) {
System.out.println(address);
System.out.println(id);
}
@RequestMapping("/met04")
public void method04(@RequestParam("name") String contactName) {
System.out.println(contactName);
}
// url:/cont03/met05?country=korea&height=200
@RequestMapping("/met05")
public void method05(@RequestParam("country") String c,
@RequestParam("height") Integer h) {
System.out.println(c);
System.out.println(h);
}
}
method01
(HttpServletRequest request) 입력할 수 있다
request.getParameter 로 name, age 받아서 출력
name, age - 쿼리 스트링으로 입력
method02
method01 에서 했던 일을 단순히 메소드의 매개변수로 작성함으로써 가능하게 함
int 여도 자동 형변환 되어 받아짐
null 값을 받기 위해서는 참조타입으로 (integer 로) 작성
name, age 정상적으로 전달받아 출력됨
method03
address, id 받아서 출력
method04
이름이 다를 경우?
@RequestParam("") 이라는 어노테이션으로 명시해주면 된다
method04(@RequestParam("name") String contactName)
name 으로 받아서 contactName 에 저장됨
method05
연습
> 정리
1. 클래스에 @Controller, @RequestMapping 작성, 메소드에 @RequestMapping 작성
@RequestMapping() 안에는 경로(value), 전달방식(method) 작성
- method 에는 대표적으로 get, post 가 있으며 post 방식의 요청은 터미널로 전달한다
2. request.getParameter 로 전달받던 값들을 메소드의 매개변수로 간단히 받을 수 있음
- 만약 이름이 다르다면 @RequestParam() 작성
* 프로젝트 run on server 로 실행하여 주소창에 경로 입력하면 콘솔에서 결과를 확인할 수 있다
전달할 값 또한 주소창에 쿼리 스트링으로 입력하면 된다
'course 2021 > Spring' 카테고리의 다른 글
Spring05 - 12/08(controller09~11) (0) | 2021.12.21 |
---|---|
Spring04 - 12/07(controller07~09) (0) | 2021.12.20 |
Spring03 - 12/06(controller04~06) (0) | 2021.12.18 |
Spring01 - 12/02 (0) | 2021.12.14 |
Spring Tool Suite (0) | 2021.12.07 |