이제껏 spring을 사용해 오면서 annotation 기능을 제대로 사용한 적이 없어서
시간이 생긴김에 공부도 할 겸 세팅을 해 보았습니다.

우선 springframework를
여기서 다운받습니다.
그리고 annotation 사용시 j2ee5 버젼 이상 또는 jdk1.6 이상의 버젼에만 있는 클래스를 사용하니 준비하시기 바랍니다.

그러면 준비는 끝이 났습니다.

일단 여기서는 j2ee를 사용하여 세팅을 하겠습니다.
eclipse에서 하나의 프로젝트를 생성합니다.


 


그 다음 아까 다운받은 springframwwork의 압축을 풀고 그 안쪽에 있는 dist 폴더의 파일들 그리고 j2ee를 설치하셨으나 제대로 연결 세팅을 안하신 분들은 javaee.jar 파일을 새로 생성한 프로젝트의 WEB-INF/lib 폴더에 옮긴 후 이클립스에서 lib경로를 잡아 줍니다.
또한 각자 필요한 jar들을 lib에 옮기고 경로를 잡아줍니다.



이제 web.xml 설정을 하겠습니다.
아래의 xml이 테스트를 위해 만들어 놓은 web.xml 전체 입니다.
내용을 보시면 아시겠지만 에제까지 해온 것들과 크게 차이가 없습니다.
 

접기

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="
http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 <display-name>annotest</display-name>
 <welcome-file-list>
  <welcome-file>index.html</welcome-file>
  <welcome-file>index.htm</welcome-file>
  <welcome-file>index.jsp</welcome-file>
 </welcome-file-list>
 <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/applicationContext.xml</param-value>
 </context-param> 
 <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
 <servlet>
  <servlet-name>annotest</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
  <servlet-name>annotest</servlet-name>
  <url-pattern>*.do</url-pattern>
  <url-pattern>/anno/*</url-pattern>
 </servlet-mapping>
</web-app>


접기


이제 설정 파일인 apllicationContext를 보겠습니다.
아래쪽의  xml이 전문입니다.

접기


<?xml version="1.0" encoding="UTF-8"?>
<!--
  - Middle tier application context definition for the image database.
  -->
<beans xmlns="
http://www.springframework.org/schema/beans"
 xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
 xmlns:p="
http://www.springframework.org/schema/p"
 xmlns:context="
http://www.springframework.org/schema/context"
 xmlns:aop="
http://www.springframework.org/schema/aop"
 xmlns:tx="
http://www.springframework.org/schema/tx"
  xsi:schemaLocation="
http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.0.xsd
      http://www.springframework.org/schema/tx
      http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
      http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
 <bean id="dataSource"
  class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
  <property name="url" value="jdbc:oracle:thin:@xxx.xxx.xx.xx:1521:ORCL" />
  <property name="username" value="xxxxx" />
  <property name="password" value="xxxxx" />
 </bean>
<!-- Transaction manager for a single JDBC DataSource -->
 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource"/>
 </bean>
<!-- Activates @Transactional for DefaultImageDatabase -->
 <tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
  <property name="configLocation" value="WEB-INF/sqlMapConfig.xml" />
  <property name="dataSource" ref="dataSource" />
 </bean>
<context:component-scan base-package="kr.co.bear">
  <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
 </context:component-scan>
 
 <import resource="app_repository.xml"/>
</beans>

접기


위의 내용을 보시면 아시겠지만 이전의 방식과 크게 다른것은 없습니다.
이전에는 빈설정을 하나하나 다 해줬는데. 
이제는 그것들이 없어지고 아래의 내용이 추가 되었습니다.


 <context:component-scan base-package="kr.co.bear">
  <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
 </context:component-scan>

위의 내용은  kr.co.bear 패키지 내부에에 있는 클래스들을 스캔한다는 내용입니다.
annotation이 Controller인 것들을 제외하고....
즉 annotation이 Service 또는 Repository인 것들만 스캔해오겠다는 내용입니다.

이제 annotest-servlet.xml을 살펴보겠습니다.
아래의 xml이 annotest-servlet.xml 전문입니다.

접기

<?xml version="1.0" encoding="UTF-8"?>
<!--
 - DispatcherServlet application context for PetClinic's web tier.
-->
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context-3.0.xsd"
               >              
 <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
  <property name="alwaysUseFullPath" value="true"/>
 </bean>
 <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" p:alwaysUseFullPath="true"/>
 <!--
  - The controllers are autodetected POJOs labeled with the @Controller annotation.
 -->
 <context:component-scan base-package="kr.co.bear">
  <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
  <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
  <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
 </context:component-scan>
 
  
 <!--
  - This bean resolves specific types of exceptions to corresponding logical
  - view names for error views. The default behaviour of DispatcherServlet
  - is to propagate all exceptions to the servlet container: this will happen
  - here with all other types of exceptions.
 <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
  <property name="exceptionMappings">
   <props>
    <prop key="org.springframework.dao.DataAccessException">dataAccessFailure</prop>
    <prop key="org.springframework.transaction.TransactionException">dataAccessFailure</prop>
   </props>
  </property>
 </bean>
 -->
 
 <!--
  - This bean configures the 'prefix' and 'suffix' properties of
  - InternalResourceViewResolver, which resolves logical view names
  - returned by Controllers. For example, a logical view name of "vets"
  - will be mapped to "/WEB-INF/jsp/vets.jsp".
 -->
 
 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
  p:prefix="/WEB-INF/jsp/"
  p:suffix=".jsp"/>
 <!--
  - Message source for this context, loaded from localized "messages_xx" files.
  - Could also reside in the root application context, as it is generic,
  - but is currently just used within PetClinic's web tier.
 
 <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"
   p:basename="messages"/>
 -->
</beans>

접기

위 의 내용을 보면 아시겠지만 아래의 두 부분이 새로은 내용이군요.
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
  <property name="alwaysUseFullPath" value="true"/>
 </bean>
 <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" p:alwaysUseFullPath="true"/>

 <context:component-scan base-package="kr.co.bear">
  <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
  <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
  <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
 </context:component-scan>


다른 두개의 내용중 위의 내용은 annotation을 사용하기위해 AnnotationHandlerMapping과 Adapter를 설정하는 것입니다.

컨트롤러를 매칭할 때에는 alwaysUseFullPath 프로퍼티의 값에 따라서 최종적으로 사용되는 경로가 결정됩니다. alwaysUseFullPath 프로퍼티의 값이 true일 경우에는 서블릿 컨텍스트 경로를 제외한 나머지 경로를 사용하여 매핑되는 컨트롤러를 검색하게 됩니다.
확장자 매핑이나 서블릿 경로 매핑에 상관없이 항상 전체 경로를 사용하고 싶다면, 다음과 같이 alwaysUseFullPath 프로퍼티의 값을 true로 지정해 주어야 하며. 참고로, alwaysUseFullPath 프로퍼티의 기본 값을 false이다.

아래쪽의 내용은 위에서 봤던것과 같이 클래스를 스캔하는 내용입니다.
이번에는 Controller만 스캔하고 Service와 Repository는 세팅을 안하겠다는 내용입니다.

여기까지 해주면 annotation 사용을 위한 기본 세팅이 완료 되었습니다.

이제 소스를 보겠습니다.
저는 소스경로를 아래와 같이 맞추었습니다.
소스경로는 각 취향이나 회사에서 사용하는 경로로 맞추시면 되겠습니다.

Controller 소스

접기


package kr.co.bear.controller;
import java.io.IOException;
import java.util.List;
import java.util.Vector;
import kr.co.bear.base.CommonConst;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import kr.co.bear.service.UserService;

@Controller

@RequestMapping ("/anno/user/*")
public class UserCtrl {
 
 private UserService userService;
 
 private int rowSize;
 
 private int pageSize;
 
 public UserCtrl(){
  this.pageSize = CommonConst.PAGESIZE;
  this.rowSize = CommonConst.ROWSIZE;
 }
 
 @Autowired
 public void setUserService(UserService userService){
  this.userService = userService;
 }
 
 
 @RequestMapping ("info/{userId}")
 public String getUserInfo(@PathVariable String userId, Model model){
  try{
   userService.getUserInfo();
   System.out.println("==========================================  userId : "+userId);
   model.addAttribute("msg","model Test");
  }catch(Exception e){
   System.out.println(e.getMessage());
  }
  return "/test";
 }
 
 @RequestMapping ("dotest.do")
 public String doTest(Model model, @RequestParam String userId){
  try{
   
   model.addAttribute("msg",".do Test");
  }catch(Exception e){
   System.out.println(e.getMessage());
  }
  return "/test";
}


import 내용중 가장중요한것은 아래에 있는 것들이다.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;


Autowired 클래스는 자동연결을 위하여 @Autowired annotation을 사용하기 위한것이다.
ex)
 @Autowired
 public void setUserService(UserService userService){
  this.userService = userService;
 }

기존에는 설정파일에서 Controller파일과 Service파일을 연결하기 위한 설정이 따로 있으나
위에 설정파일에서 보면 알듯이 2개의 연결설정이 따로없다.
위와같이 @Autowired를 사용하면 ServiceImpl에 @Service("userService") 이런식으로 설정시
자동으로 연결된다.

Controller 클래스는 @Controller annotation을 사용하기 위한 것이다.
Model 클래스는 외부에 값을 전달하기 위해서 사용하는 클래스이다.

ex)
 public String doTest(Model model){
  try{
  
   model.addAttribute("msg",".do Test");
  }catch(Exception e){
   System.out.println(e.getMessage());
  }
  return "/test";
 }

Parameter에 Model클래스를 넣은것은 Model을 사용하겠다고 선언해놓은것과 같은의미이다.
model.addAttribute("msg",".do Test"); 이렇게 쓰면 Model 안쪽에 값을 저장할 수 있다.
jsp부분에서 사용하는 부분은 나중에 보도록하겠다.

RequestMapping 클래스는 @RequestMapping annotation을 사용해서 페이지 경로를 지정하기 위해 사용하는 클래스이다.
@RequestMapping는 클래스 위 또는 메소드 위에 사용할 수있다.
소스에 보면 클래스 위에 @RequestMapping ("/anno/user/*") 이 있는것을 볼 수있다.
이것은 경로를 /anno/user/ 밑으로 지정해준것이다.

그리고 메소드 위에 @RequestMapping ("info/{userId}"), @RequestMapping ("dotest.do")가 있는것을 볼 수있다.
이것은 클래스위에 설정한 /anno/user/ 경로밑에 들어갈 경로이다.

@RequestMapping ("info/{userId}")에서 {userId} 이부분은 경로의 맨 마지막의 값을 userId로 사용하겠다는 것이다.
이 방식으로 사용하기 위해서 PathVariable 클래스를 사용한다.
 그리고 메소드의 파라메터로 "@PathVariable String userId"를 넣어주다.
"@PathVariable String userId"의 의미는 RequestMapping에 있는 userId를 String형태인 userId 객체에 값을넣어 사용하겠다는 의미이다.

RequestParam 클래스는 @RequestParam annotation 을 사용해서 넘어온 파라메터 값을 받아 사용하기 위한 클래스이다.
사용하는 방법은 메소드의 파라메터로 @RequestParam String userId 를 넣어준다.
"@RequestParam String userId"의 의미는 파라메터로 넘어오는 userId의 이름으로 된 데이타를  String형태인 userId 객체에 값을넣어 사용하겠다는 의미이다.


밑에 ServiceImpl 과 DaoImpl 소스코드를 올려두나 이전 방법과 크게 다를건 없을것 같다.

ServiceImpl 소스

접기

package kr.co.bear.service.impl;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import kr.co.bear.dao.UserDao;
import kr.co.bear.service.UserService;

@Service("userService")
public class UserServiceImpl implements UserService {
 
 private UserDao userDao;
 
 @Autowired
 public void setUserDao(UserDao userDao){
  this.userDao = userDao;
 }
 
 public String getUserInfo() throws Exception{
  String str = userDao.getUserInfo(); 
  return str;
 }
}


접기


DaoImpl 소스

접기

package kr.co.bear.dao.impl;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import com.ibatis.sqlmap.client.SqlMapClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import kr.co.bear.dao.UserDao;
import kr.co.bear.base.DSqlMapClientSupport;
@Repository("userDao")
public class UserDaoImpl extends DSqlMapClientSupport implements UserDao{
 
 public String getUserInfo(){
  getSqlMapClientTemplate().queryForObject("kr.co.bear.dao.user.memberDetail", "1");
  return "Dao getUserInfo";
 }
}


접기


마지막으로 jsp 페이지에서 Model에 담은 데이타를 가져와서 사용하는 방법을 알아보겠습니다.
 
test.jsp 소스

접기

<%
String msg = (String)request.getAttribute("msg");
%>
<%=msg%>

접기

위쪽의 Controller 소스에서 Model에 addAttribute로 값을 저장하게 되면 저장한 값이 그대로 request에 저장이 되어집니다.
따라서 소스에서는 request.getAttribute("msg"); 처럼 Model에 저장한 키값으로 불러오면 데이타를 사용할 수 있습니다.


용량 문제상 lib를 제외하고 소스를 올려 놓으니 참고하시기 바랍니다.

 

 

annotest.zip

[ 출처 ] http://gaury.kr/122


'Spring' 카테고리의 다른 글

[Spring] spring 3.x log4j 사용  (0) 2012.08.10
[Spring] annotation  (0) 2012.08.09
[Spring] 테스트 war 파일  (0) 2012.02.24
[Spring] eclipse(indigo) + maven + springMVC (3)  (0) 2012.02.23
[Spring] eclipse(indigo) + maven + springMVC (2)  (0) 2012.02.23

+ Recent posts