26.1 스프링 애너테이션이란? 920p
26.2 스프링 애너테이션 이용해 URL 요청 실습하기 921p
26.3 스프링 애너테이션 이용해 로그인 기능 구현하기 925p
26.4 @Autowired 애너테이션 이용해 빈 주입하기 936p
26.1 스프링 애너테이션이란?
920p
스프링 2.5 - DI나 AOP 등의 기능은 XML 파일로 설정 후 애플리케이션에서 사용
스프링 3.0 - DI 등 자바 코드와 관련된 설정은 직접 코드에서 할 수 있도록 애너테이션 기능을 제공
현재 스프링 기반 애플리케이션에서는 XML에서 설정하는 방법과 애너테이션 기능을 사용하는 방법 두 가지를 혼합해서 사용하고 있음
1. 스프링 애너테이션 제공 클래스
스프링에서 제공하는 애너테이션 관련 클래스를 XML 설정파일에서 빈으로 설정해야 스프링에서 애너테이션을 사용할 수 있음
▼브라우저 URL 오청 처리 애너테이션 관련 클래스
클래스 | 기능 |
DefaultAnnotationHandlerMapping | 클래스 레벨에서 @RequestMapping을 처리함 |
AnnotationMethodHandlerAdapter | 메서드 레벨에서 @RequestMapping을 처리함 |
2. <context:component-scan> 태그 기능
<context:component-scan base-package="패키지이름" />
=> 애플리케이션 실행 시 해당 패키지에서 애너테이션으로 지정된 클래스를 빈으로 생성해줌
▼<context:componet-scan> 태그로 지정한 패키지에 있는 클래스에 지정하는 애너테이션
애너테이션 | 기능 |
@Controller | 스프링 컨테이너가 component-scan에 의해 지정한 클래스를 컨트롤러 빈으로 자동 변환함 |
@Service | 스프링 컨테이너가 component-scan에 의해 지정한 클래스를 서비스 빈으로 자동 변환함 |
@Repository | 스프링 컨테이너가 component-scan에 의해 지정한 클래스를 DAO 빈으로 자동 변환함 |
@Component | 스프링 컨테이너가 component-scan에 의해 지정한 클래스를 빈으로 자동 변환함 |
위의 애너테이션이 설정된 클래스들은 스프링 실행 시 자동으로 빈으로 생성됨
26.2 스프링 애너테이션 이용해 URL 요청 실습하기
921p
새 프로젝트 pro26 생성
WebContent/WEB-INF - action-servlet.xml 생성 : 스프링 애너테이션 실습을 위한 xml 설정파일
[ action-servlet.xml ] pro26/WebContent/WEB-INF/action-servlet.xml
...
- InternalResourceViewResolver 클래스 빈 - 뷰 처리 위함
- DefaultAnnotationHandlerMapping 클래스 빈 - 클래스 레벨에서 @RequestMapping을 처리함
- AnnotationMethodHandlerMapping 클래스 빈 - 메서드 레벨에서 @RequestMapping을 처리함
- <context:component-scan base-package="com.spring"/> - com.spring 패키지에 존재하는 클래스에 애너테이션이 적용되도록 설정함
애너테이션 기능을 수행하는 자바 클래스와 JSP 파일을 추가함
src/com/spring/ex01 패키지 - MainController
WebContent/WEB-INF/views/test - main.jsp
[ MainController ] pro26/src/com/spring/ex01/MainController.java
- @Controller("mainController") - @Controller 애너테이션을 이용해 MainController 클래스를 빈으로 자동 변환함, 주로 컨트롤러 클래스에 위치하는 애너테이션임, 빈 id는 애너테이션에 작성한 "mainController"임
- @RequestMapping("/test") - 첫번째 단계의 URL 요청이 /test이면 해당 클래스(빈)을 요청함
- @RequestMapping(value="/main1.do", method=ReqyestMethod.GET) - 두번째 단계의 URL 요청이 /main.do 이면 해당 애너테이션이 적용된 (MainController 빈 - ) main1() 메서드를에게 요청함, method=RequestMethod.GET으로 지정하게 되면 요청 시 GET 방식으로 해당 메서드가 호출됨
- main1() - /test/main1.do 요청을 처리하는 메서드, ModelAndView 객체 mav 생성하여 ("msg", "main1") 을 추가함(addObject()), mav.setViewName("main") 을 지정, mav를 return함
- @RequestMapping(value="main2.do", method=RequestMethod.GET) - 두번째 단계의 URL 요청이 /main2.do 이면 해당 애너테이션이 적용된 main2() 메서드가 요청됨, GET방식으로 해당 메서드 호출됨
- main2() - ModelAndView 객체 mav 생성, ("msg", "main2") 를 mav에 추가 후 mav.setViewName("main"), mav를 return
[ main.jsp ] pro26/WebContent/WEB-INF/views/test/main.jsp
컨트롤러에서 mav에 뷰 이름으로 설정한 main.jsp임 (mav.setViewName("main"))
...
${msg} 로 mav에 바인딩된 데이터 출력됨, /main1.do 로 요청시 "main1", /main2.do 로 요청 시 "main2" 가 출력됨
26.3 스프링 애너테이션 이용해 로그인 기능 구현하기
925p
src/com/spring/ex02 패키지 - LoginController, LoginVO 생성
WebContent/WEB-INF/views/test - loginForm.jsp, main.jsp, result.jsp 생성
WebContent/WEB-INF - action-servlet.xml, web.xml 생성
[ web.xml ] pro26/WebContent/WEB-INF/web.xml
- <filter> - CharacterEncodingFilter 클래스, param-name -> encoding, param-value -> UTF-8 지정 : 한글 깨짐 방지 위해 한글 필터 기능을 사용함
- <filter-maiing> - 위의 <filter> 에서 작성한 <filter-name>과 동일한 <filter-name> 작성, <url-pattern>은 /* 로 설정
[ LoginController ] pro26/src/com/spring/ex02/LoginController.java
로그인창(loginForm.jsp)에서 입력한 id, 이름을 JSP(result.jsp)에서 출력할 수 있도록 함
- @Controller("loginController") - 컨트롤러 빈 자동 생성
- @RequestMapping(value={"/test/loginForm.do" , "/test/loginForm2.do}, method={RequestMethod.GET}) - 두 요청 URL 모두 해당 애너테이션이 설정된 loginForm() 메서드를 호출함, GET 방식으로 메서드를 요청함
- loginForm() - ModelAndView 객체 mav 생성해서 mav.setViewName("loginForm") 으로 jsp 이름 설정 후 mav return함
- @RequestMapping(value="/test/login.do", method={ RequestMethod.GET, RequestMethod.POST }) - GET방식과 POST방식 모두 해당 메서드로 처리할 수 있음
- login() - request의 인코딩 설정, mav 객체 생성, 뷰 이름 "result" 로 설정, request.getParameter()로 "userID"와 "userName"을 가져와 변수에 저장 후 mav에 바인딩(addObject() 메서드 이용), mav return함
* @RequestMapping에서 value={"url1", "url2", ...} 와 같이 작성하여 여러 개의 요청 URL을 하나의 메서드로 처리하도록 할 수 있음
[ loginForm.jsp ] pro26/WebContent/WEB-INF/views/test/loginForm.jsp
<form> 태그의 action="${contextPath}/test/login.do" => LoginController의 login() 메서드에게 요청됨
id와 사용자 이름을 입력받을 수 있는 input text박스를 만들어줌
[ result.jsp ] pro26/WebContent/WEB-INF/views/test/result.jsp
로그인창 loginForm.jsp 에서 입력된 id와 이름이 나타나도록 작성함
${userID}, ${userName} 등으로 출력, 컨트롤러 - login() 메서드에서 ModelAndView 객체 mav에 바인딩되어있음
1. 메서드에 @RequestParam 적용하기
928p
브라우저에서 전송한 매개변수를 일일이 getParameter() 메서드로 값을 얻어오는 것은 번거로움
=> @RequestParam 애너테이션을 메서드에 적용하면 쉽게 값을 얻을 수 있음
@RequestParam("매개변수의 name") -> 매개변수 value를 가져옴
[ LoginController ] pro26/src/com/spring/ex02/LoginController.java
- login2() - public ModelAndView login2 ( @RequestParam("userID) String userID, @RequestParam("userName") String userName ) => 매개변수 name이 "userID" 이면 그 값을 변수 userID에 자동으로 저장함, userName도 마찬가지임, getParameter()로 매개변수 가져와 변수에 저장하지 않아도
@ReqeustParam 애너테이션에 의해 메서드 안에서 바로 userID와 userName 변수를 사용할 수 있으며 이미 값이 저장되어있음mav.addObject("userName", userName)
[ loginForm.jsp ] pro26/WebContet/WEB-INF/test/loginForm.jsp
로그인 창, id와 이름을 입력받아서 컨트롤러로 전송하도록 함
<input type="text" name="userID"> -> @RequestParam 에서 지정한 "userID" 와 name이 같음
<input type="text" name="userName"> -> @RequestParam 에서 지정한 "userName" 와 name이 같음
2. @RequestParam 의 required 속성 사용하기
930p
@RequestParam - required 속성 : 반드시 전달해야 하는 필수 매개변수 / 필수가 아닌 매개변수를 설정할 수 있음
- required 속성 생략 시 기본값 true가 적용됨
- required=true : 메서드 호출 시 반드시 지정한 이름의 매개변수를 전달해야 함, 없으면 예외 발생
- required=false : 메서드 호출 시 지정한 이름의 매개변수가 전달되면 값을 저장, 없으면 null을 할당함
[ LoginController ] pro26/src/com/spring/ex02/LoginController.java
public ModelAndView login2 ( @RequestParam("userID") String userID, // required 생략 시 true
@RequestParam(value="userName", required=true) String userName,
@RequestParam(value="email", required=false) String email,
HttpServletRequest request,
HttpServletResponse response) ... {
...
}
=> email은 필수 매개변수가 아니므로
로그인 창에서 name이 "email" 인 input 태그에 값이 전달되면-> @RequestParam 으로 값을 가져와 mav에 바인딩하므로 결과창에 값이 출력됨
"email" input 태그에 값이 입력되지 않더라도 @RequestParam 에 의해 email 변수에 null이 할당됨
필수 매개변수인 userID와 userName이 작성되지 않은 채로 컨트롤러에 넘어오면 예외 발생함
3. @RequestParam 이용해 Map에 매개변수 값 설정하기
931p
전달되는 매개변수 값들을 Map에 저장할 수도 있음
@RequestParam Map<String, String> info
: 이름이 info 인 Map에 매개변수 이름을 key로, 매개변수 값을 value로 저장함
[ LoginController ] pro26/src/com/spring/ex02/LoginController.java
...login3( @RequestParam Map<String, String> info, ...)
전송된 매개변수들을 자동으로 Map에 저장하도록 함
매개변수의 name은 key에, 값은 value에 저장됨,
메서드 내에서 Map이름.get("key이름") 으로 값을 가져와 사용할 수 있음
=> info.get("userID") 등으로 userID, userName의 값을 가져와 변수에 저장함,
mav.addObject("info", info) 로 설정한 Map 이름 그대로 바인딩 할 수도 있음
jsp에서는 ${info.userID} 등으로 바인딩된 값을 가져와 출력할 수 있음
4. @ModelAttribute 이용해 VO에 매개변수 값 설정하기
933p
@ModelAttribute 애너테이션을 이용하면 VO 클래스의 속성에 매개변수의 값들이 자동으로 설정되게 할 수 있음
@ModelAttribute("info") LoginVO loginVO
-> 전달된 매개변수에 대해 LoginVO 클래스 객체 loginVO를 생성
-> 매개변수의 이름과 같은 이름의 VO의 속성에 매개변수 값을 저장
-> "info" 라는 이름으로 바인딩함
[ LoginController ] pro26/src/com/spring/ex02/LoginController.java
... login4(@ModelAttribute("info") LoginVO loginVO, ...)
-> 전달된 매개변수 값을 loginVO 클래스의 이름이 같은 속성에 자동으로 설정함,
값이 설정되고 나면 jsp에서 "info"라는 이름으로 loginVO의 속성에 접근이 가능함 (addObject() 이용할 필요 없음)
=> jsp - ${info.userID} 등으로 loginVO 의 속성값에 접근가능
5. Model 클래스 이용해 값 전달하기
934p
Model 클래스 - 메서드 호출 시 JSP로 값을 바인딩하여 바로 전달할 수 있음,
Model.addAttribute() 메서드 = ModelAndView.addObject() 메서드와 같은 기능을 함
Model 클래스는 따로 뷰 정보를 전달할 필요가 없을 경우 사용하면 편리함
[ LoginController ] pro26/src/com/spring/ex02/LoginController.java
...login5 ( Model model, ...request, ..response)
-> login5 메서드 호출시 Model 클래스 객체를 생성함,
메서드 내에서 model.addAttribute("userID", "hong") 등으로 작성하여
JSP에 전달할 데이터를 model 객체에 addAttribute() 메서드를 이용해 바인딩 할 수 있음
(해당 메서드는 뷰 이름 "result"를 return함)
=> model에 바인딩한 정보는 JSP에서 ${ userID } 등으로 접근할 수 있음
26.4 @Autowired 애너테이션 이용해 빈 주입하기
936p
기존 - 빈 주입 시 XML에서 설정하여 애플리케이션이 실행될 때 빈을 주입 (XML 파일 복잡, 사용 및 관리 불편)
=> @Autowired 애너테이션 사용 - 자바코드에서 직접 빈을 생성하여 사용함
- 기존 XML 파일에서 각각의 빈을 DI로 주입했던 것을 코드에서 애너테이션으로 자동으로 수행함
- 별도의 setter나 생성자 없이 속성에 빈을 주입할 수 있음
WebContent/WEB-INF/config - action-mybatis.xml, jdbc.properties (24장 파일 복붙)
WebContent/WEB-INF - action-servlet.xml, web.xml
[ web.xml ] pro26/WebContent/WEB-INF/web.xml
- <Listener> - ContextLoaderListener 클래스
- <context-param> - name=contextConfigLocation, value=/WEB-INF/config/action-mybatis.xml
=> 애플리케이션이 실행될 때 action-mybatis.xml을 읽어들이도록 함
*** ContextLoaderListener 과 RootApplicationContext / WebApplicationContext
- RootApplicationContext 는 최상위 ApplicationContext 이며, WebApplicationContext 의 부모 Context 이며, 자식에게 자신의 설정을 공유함. 단, 자신은 자식인 WebApplicationContext의 설정에 접근하지 못함
- WebApplicationContext 는 Servlet 단위의 ApplicationContext임, 부모인 RootApplicationContext 의 설정에 접근할 수 있음
- ContextLoaderListener 는 RootApplicationContext 를 생성하는 클래스

- web.xml에서 <Listener> 로 ContextLoaderListener를 설정하고
<context-param> 의 contextConfigLocation 설정파일(security-context.xml, applicationContext.xml)을 읽어서 RootApplicationcontext를 생성함 (빨간색 블록의 contextConfigLocation 을 읽어서 RootApplicationContext 생성)
- web.xml에서 <servlet> 으로 DispatcherServlet 클래스를 설정하고, <init-param>에서 <param-name> 에 contextConfigLocation을, <param-value>에 servlet-context.xml, mybatis-context.xml 등을 설정하여 이를 이용해 WebApplicationContext를 생성함 (파란색 블록의 contextConfigLocation 을 읽어서 WebApplicationContext 생성)

출처 https://tlatmsrud.tistory.com/43
[ action-servlet.xml ] pro26/WebContent/WEB-INF/action-servlet.xml
- InternalResourceViewController 클래스 빈 - prefix의 value를 "/WEB-INF/views/member/" 로 설정하여 JSP 경로를 변경함(원래는 /WEB-INF/views/test/ 였음)
- DefaultAnnotationHandlerMapping 클래스 빈
- AnnotationMethodHandlerAdapter 클래스 빈
- <context:component-scan> 으로 com.spring 패키지를 설정 (해당 패키지 내 클래스는 자동으로 빈으로 생성됨)
[ action-mybatis.xml ] pro26/WebContent/WEB-INF/config/action-mybatis.xml
스프링에서 제공하는 클래스의 빈을 사용할때는 여전히 XML로 설정해야 하지만
MemberDAO 등 개발자가 만들어준 클래스는 자바코드에서 애너테이션을 통해 바로 빈으로 사용할 수 있음
- dataSource 빈 - PooledDataSource 클래스, jdbc.properties에서 driverClassName 등 db연결에 필요한 값을 속성에 설정
- sqlSessionFactory 빈 - SqlSessionFactoryBean 클래스, dataSource 속성에 dataSource빈을 주입, configLocation 속성에 modelConfig.xml, mapperLocations 속성에 /mappers/*.xml 을 설정함
- sqlSession 빈 - SqlSessionTemplate 클래스, <constructor-arg에 sqlSessionFactory 빈 주입
- memberDAO 빈 설정 부분은 주석처리함
회원 관리 기능 매퍼 파일을 설정해보자. (24장과 구조 및 파일 내용 동일)
src/mybatis/mappers 패키지 - member.xml
src/mybatis/model 패키지 - modelConfig.xml
회원 관리 기능 관련 자바 파일과 JSP 준비 (JSP는 24장과 동일)
src/com/spring/member 패키지
- controller 패키지 - MemberController.java, MemberControllerImpl.java
- dao 패키지 - MemberDAO.java, MemberDAOImpl.java
- service 패키지 - MemberService.java, MemberServiceImpl.java
- vo 패키지 - MemberVO.java
WebContent/WEB-INF/views/member 폴더 - listMembers.jap, memberForm.jsp, modMember.jsp
[ MemberControllerImpl ] pro26/src/com/spring/member/controller/MemberControllerImpl.java
- @Controller("memberController") 애너테이션 - 해당 클래스에 대해 id가 memberController인 빈을 자동 생성
- @Autowired - id가 클래스 내 선언된 속성(private MemberService memberService)인 빈을 자동 주입함
@Autowired는 속성 앞에 설정되며 해당 속성의 이름과 id가 같은 빈을 자동 주입해줌
...
[ MemberServiceImpl ] pro26/src/com/spring/member/service/MemberServiceImpl.java
- @Service("memberService") - 해당 클래스로 id가 "memberService" 인 빈을 자동 주입함
[ MemberDAOImpl ] pro26/src/com/spring/member/dao/MemberDAOImpl.java
- @Repository("memberDAO") - 해당 클래스로 id가 "memberDAO"인 빈을 자동 주입함
- sqlSession 속성에 id가 sqlSession인 빈이 @Autowired를 통해 자동 주입됨
[ MemberVO ] pro26/src/com/spring/member/vo/MemberVO.java
- @Component("memberVO") - 해당 클레스로 id가 "memberVO" 인 빈을 자동 생성함
=> 여전히 스프링에서 제공하는 클래스로 생성되는 빈(sqlSession 등)은 XML 파일에서 설정해서 생성해야 함
'(책) 자바 웹을 다루는 기술' 카테고리의 다른 글
Chap 27 메이븐과 스프링 STS 사용법 (0) | 2023.09.21 |
---|---|
Chap 25 스프링 트랜잭션 기능 사용하기 (0) | 2023.09.19 |
Chap 24 스프링과 마이바티스 연동하기 (0) | 2023.09.19 |
Chap 23 마이바티스 프레임워크 사용하기 (0) | 2023.09.19 |
Chap 22 스프링 JDBC 기능 (0) | 2023.09.17 |