SpringMVC에서 빈을 생성되는 시점과 소멸되는 시점에 대한 설정을 Scope를 이용하여 할 수 있다.
Spring Core에서 Scope는 객체를 소멸시키지 전까지 한개의 객체만을 생성하는 Singleton과 getBean하여 빈을 생성할 때마다 새로운 객체를 생성하는 prototype이 있었다.
SpringMVC에서는 Request, Session, Application을 추가로 제공한다.
먼저 RequestScope에 대해서 알아보자.
1. RequestScope
request객체에 대해 조금 생각을 해보자. 웹 브라우저에 의해 새로운 요청이 발생하면 브라우저는 서버에 요청에 관련된 정보를 전송하게 된다. 이를 받은 서버는 브라우저가 보낸 요청 정보들을 보관하기 위해서 HttpServletRequest객체를 생성하여 요청 정보를 담아두게 된다. 요청정보가 담겨 있는 HttpServletRequest객체는 응답결과가 브라우저로 전송될 때까지 유지가 되며 사용이 가능하다!
새로운 요청이 발생하여 응답결과가 브라우저로 전달 될때까지 요청정보가 담겨 있는 Request객체를 사용할 수 있다. 이러한 사용범위를 RequestScope라고 부른다. HttpServletRequest객체에는 개발자가 필요에 의해 데이터나 객체를 저장할수 있고 RequestScope내에서 사용이 가능하다.
1.1 HttpServletRequest 사용
위와 같이 request객체를 활용할 수 있었다. requestScope 메소드를 보면 result메소드로 forward를 하였다. 만약 응답결과로 redirect를 쓴다면 request객체를 웹 브라우저로 전달하면서 request객체는 소멸되고 redirect된 메소드에서 request객체는 새로 생성된다. forward하면 아직 응답결과를 브라우저로 전달하지 않았기 때문에 request객체가 소멸되지 않아서 출력을 할 수 있다. 물론, View에서도 Attribute로 담은 객체를 사용할 수 있다!
<body>
<h1> result </h1>
data1 : ${data1}
</body>
이런식으로!!
1.2 Model사용
Model을 사용하는 방법도 크게 다르지 않다. 다만 Model을 사용하여 포워딩을 했는데 받는 result메소드에서는 왜 Model로 받지 않고 HttpServletRequest를 이용하여 받았는지 의문이 들 수 있다.
model.addAttribute하면 Model에 저장되는 것이 아니라 Request객체에 저정하는 것이다. 그렇기 때문에 받을 때도 HttpServletRequest를 이용해서 받았다. 물론, Request영역에 저장한 것이기 때문에 View에서도 활용이 가능하다.
<body>
<h1> result </h1>
data1 : ${data1}
</body>
1.3 ModelAndView사용
ModelAndView도 Model과 마찬가지로 사용하면 되겠다. ModelAndView예제에서는 클래스자체를 포워딩을 해보자.
UserDataBean이라는 POJO클래스를 만들어서 활용해보자. 저 클래스는 빈으로 등록하여서 클라이언트가 값을 요청하면 매개변수로 받아서 활용할 수도 있겠다. 그냥 예제니깐.. 이렇게 보았다.
홍길동, qwer이라는 값을 프로퍼티에 세팅해주고, addObject를 이용해서 "bean"이라는 이름으로 모델에 담은 후 result로 forward를 해주었다.
Model과 마찬가지로 MoodelAndView도 MoodelAndView객체가 저장되어 넘어가는 것이 아니라, Request객체에 저장을 하는 것이다. 그러므로 포워딩된 result메소드에서 HttpServletRequest를 이용하여 받으면 이용할 수 있다.
<body>
<h1> result </h1>
username : ${bean.userName }
userid : ${bean.userId }
</body>
View에서도 이렇게 이용할 수 있겠다.
1.4 @ModelAttribute 사용
@ModelAttribute를 통해서 주입받은 객체는 Request영역에 자동으로 저장이 된다. 만약 위와 같이 ModelAttribute를 포워딩했다면 ModelAttribute로 받는 것이 아니라 HttpServletRequest로 받아야 한다. 넘겨준 곳에도 ModelAttribute가있다면 새로운 객체가 주입되고, 덮여 쓰이게 되어 다른 빈 객체가 저장된다. ModelAttribute를 쓸때에도 역시 HttpServletRequest를 써주자.
<body>
<h1> result </h1>
username : ${bean.userName }
userid : ${bean.userId }
</body>
2. RequestScope 빈 주입
이제 본격적으로 RequestScope를 사용해보자.
공통적으로 이 POJO클래스를 빈으로 등록하여 사용할 것이다. Java Configuration 파일과 Xml파일에 빈을 등록하는 어노테이션과 속성이 약간씩 차이가 있어서 예제마다 다르게 설정을 한것을 설명해보겠다.
2.1 @Autowired - 타입을 통한 주입
자바 빈 등록파일이다. @Bean과 함께 @RequestScope를 사용해줌으로써 이 빈의 scope는 request로 설정해준다.
@RequestScope로 지정하면 이 빈 객체는 새로운 요청이 발생되었을 때 빈이 주입된다.
예를 들어, forward는 새로운 요청을 하는 것이 아니기 때문에(브라우저에게 새로운 요청을 하는것이 아닌 서버단에서 전달하는 것) 원래 있는 빈을 그대로 이용하게 되겠다. 다른 빈 객체가 새롭게 주입되지 않는 이상 객체는 계속 유지가 된다.
@Autowired를 사용하여 타입을 통한 주입을 해주었다. @Autowired을 통해 빈을 등록해주는 순간, 새로운 요청이 발생한 것이기 때문에 DataBean1타입의 빈 객체가 등록이 되고, 새로운 빈 주입이 되지 않는 이상 저 빈 객체는 계속 유지가 될 것이다!!
@RequestScope는 '새로운 요청이 발생하면 빈을 주입하겠다.' 라는 의미이지 Request에 저장을 하는 것은 아니다. 그러므로 View단에서는 바로 사용할 수 없고 Model을 이용하여 넘겨주어야 한다.
<body>
<h1> result </h1>
data1 : ${bean.data1 }
data2 : ${bean.data2 }
</body>
만약, 빈을 Java가 아니라 xml파일에서 등록한다면??
이렇게 해주면 되겠다.
2.2 @Resource(name="빈 이름") - 이름을 통한 주입
자바 빈 등록파일에 다음과 같이 빈이 이름으로서 등록이 되어 있다.
그러면 @Resource를 이용해서 이름으로 등록된 빈을 받아주면 되겠다. 2.1과 다를건 없다. 빈에는 @RequestScope가 설정되어 있기 때문에 새로운 요청이 발생될 때 빈이 주입된다. 또한, Request영역에는 저장이 안되기 때문에 Model을 사용해야지만 View단에서 사용할 수 있다.
<body>
<h1> result </h1>
data1 : ${bean.data1 }
data2 : ${bean.data2 }
</body>
만약, 빈을 Java가 아니라 xml파일에서 등록한다면??
이렇게 id를 등록해주고 저 아이디를 사용하여 @Resource로 가져오면 되겠다.
2.3 @Component
이번에는 컴포넌트를 이용해보자.
등록할 빈 클래스에다가 @Component와 @RequestScope를 지정해준다.
컴포넌트 어노테이션을 붙였으니 자바 빈 등록파일에 빈을 따로 등록하지 않아도 DataBean1형의 빈이 등록되었을 것이다. 우리는 @ComponentScan만 잘 해주면 되겠다.
@Autowired를 이용하여 타입을 통한 자동주입을 해주고 위의 예제들과 유사한 방식으로 사용해줄 수 있다.
만약, xml파일에 빈을 등록하는 프로젝트라면~?
이렇게 servlet-context.xml에 컴포넌트 스캔을 추가해주면 되겠다.
'JAVA > Spring MVC' 카테고리의 다른 글
Spring MVC에서의 빈 관리 (ApplicationScope) (0) | 2020.04.28 |
---|---|
Spring MVC에서의 빈 관리 (SessionScope) (0) | 2020.04.27 |
Redirect와 Forward (0) | 2020.04.24 |
Form 커스텀 태그 (0) | 2020.04.24 |
ViewResolver 에게 전달하기 (0) | 2020.04.24 |