Programing/Spring

Spring Basic

BeomJun.Kwon 2022. 3. 3. 14:24

 

Spring Basic

 

 


구성요소

  • DispatcherServlet : 클라이언트 요청을 받아서, 컨트롤러에 요청을 전달하고 컨트롤러가 리턴한 결과 값을  View 에 전달하여 응답을 생성한다. (Struts 의 ActionServlet)
  • HandlerMapping : 클라이언트 요청 URL 을 어떤 컨트롤러가 처리할지를 결정한다. (struts-config.xml 의 역할)
  • Controller : 요청을 처리하고 결과를 리턴한다 (Struts 의 Action)
  • ModelAndView : 컨트롤러가 처리한 결과 정보 및 뷰에 관련한 정보를 담는 객체 (struts의 forward 기능 포함)
  • ViewResolver : 컨트롤러 처리 결과를 생성할 뷰를 결정View : 컨트롤러 처리 결과 화면을 생성하는 객체
     


기본적인 Spring MVC 설정 잡기

  • web.xml 에 DispatcherServlet 의 설정을 잡는다. (여기서 잡은 이름-servlet.xml 파일이 설정파일이 된다)
  • HandlerMapping 을 이용 URL 과 Bean의 name 속성을 같은 것으로 설정한다. 
<bean id="beanName" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
<!-- c.f.) 만약 이 설정을 넣지 않으면 자동으로 이 HandlerMapping 이 적용된다. -->
  • Spring 설정 파일에 name에 URL 을 입력하고 class에 Controller 를 지정한 뒤 작성한다.
  • Controller 에서는 ModelAndView 객체를 생성해서 직접 갈 곳을 지정해준다.

 


HandlerMapping 구현 클래스

  • SimpleUrlHandlerMapping : 패턴과 컨트롤러 이름을 비교하여, URL 이 패턴에 매칭될 경우 지정 컨트롤러 사용
  • BeanNameUrlHandlerMapping(default) : URL 과 일치하는 bean 이름의 컨트롤러 사용
  • ControllerClassNameHandlerMapping : URL 과 매칭되는 클래스 이름을 갖는 빈을 컨트롤러 사용
  • DefaultAnnotationHandlerMapping : @RequestMapping 어노테이션을 이용 컨트롤러 사용

참고1) web.xml에 <url-pattern> 을 '/path/*'  같이 설정을 할 경우 전체 경로를 다 사용하고 싶으면 HandlerMapping

           설정시 <property name="alwaysUseFullPath" value="true" /> 를 넣어서 설정을 잡는다.

참고2) 복수개의 HandlerMapping 구현시 property 로 order 를 넣어서 순서를 정해줄 수도 있다.

 


Controller 구현 클래스

  • Controller, AbstractController : 단순 처리용
  • AbstractCommandController : 요청 파라미터를 객체에 자동으로 저장해 주고 검증기능 제공한다.
  • SimpleFormController : 폼을 출력하고 폼에 입력한 데이터를 처리할때 사용(가장많이 사용)
  • AbstractWizardFormController : 여러 페이지에 걸쳐 데이터 입력시 사용(단게적인 페이지 설정이 쉬움)
  • ParameterizableViewController, UrlFilenameViewController : 단순히 뷰로 바로 전달할때 사용
  • MultiActionController : 비슷한 로직을 수행하는 기능들을 하나의 컨트롤러로 구현할때 사용
     


ViewResolver 구현 클래스

  • InteralResourceViewResolver(default) : JSP 나 tiles 연동 위한 View 객체를 리턴
  • VelocityViewResolver : Velocity 연동을 위한 View 객체를 리턴
  • BeanNameViewResolver : 뷰 이름과 똑같은 이름의 Bean 객체를 View 로 이용
  • ResourceBundleViewResolver : 뷰 이름과 View 객체간 매핑 정보를 특정 자원 파일에 저장해서 사용
  • XmlViewResolver : 뷰 이름과 View 객체간 매핑 정보를 XML 파일에 저장해서 사용
     


Validator 와 Errors
  1) Validator 인터페이스를 상속받은 클래스로써 command(form)에 들어오는 값들에 대한 검증이 가능하다
  2) 주요 메소드 (Validator 인터페이스를 상속받는 클래스에서 구현해야 하는 메소드)
   <1> boolean supports(Class clazz) : 인자값으로 들어오는 클래스가 검증대상인지 확인하는 메소드
   <2> void validate(Object target, Errors errors) : 실제 검증 메소드 (target 은 command 객체이다)
    a. ValidationUtils 클래스를 통해서 데이터의 검증을 한다. 혹은 Errors 를 이용해 에러를 저장한다.
    b. 이렇게 저장된 오류는 jsp 화면에서 <form:errors> 를 이용해 오류를 보여주는 것이 가능하다.
    c. Errors 에는 전체적인 오류를 저장하기 위한 reject 메소드와 특정 필드에 대한 오류를 저장하기 위한
     rejectValue 메소드가 있다.
  3) command 가 쓰이는 Controller xml 설정에 프로퍼티로써 validator 를 적용시켜야 한다.
   ex) <property name="validator" ref="reboardValidator"></property>
 


HandlerInterceptor

컨트롤러에서 요청을 처리하기 전이나 후에 뭔가를 수행하고 싶을때 사용한다.
  1) 주요 메소드
   <1> boolean preHandle() : 컨트롤러에서 요청이 처리되기 전 실행
   <2> void postHandle() : 컨트롤러가 요청을 처리한 후에 실행
   <3> void afterCompletion() : 응답이 완전히 끝난 뒤 실행되는 메소드
  2) 사용방식
   HandlerInterceptor 를 상속받거나 원하는 메소드만 구현할 수 있는
   HandlerInterceptorAdaptor 를 상속받은 클래스를 xml 에서 HandlerMapping 설정에
   <property name="interceptors"> 로 등록할 수 있다.

 

 

 

 

transaction (트랜젝션)

ACID : 트랜젝션에서 추구했던 기본 4요소

  • Atomicity : 원자성  모든 작업이 하나의 단위로 이루어져야 한다 (다 수행되던가 없던일 하던가)
  • Consistency : 일관성  DB가 트랜젝션 작업중 일관된 데이터를 유지해야 한다
  • Isolation : 독립성   다른 트랜젝션과 독립적으로 작업이 수행되어야 한다.
  • Durability : 내구성  일단 커밋된 데이터는 계속해서 유지되어야 한다. 시스템 오류라 할지라도..
     


프로그램적인 트랜젝션

  1. TransactionTemplate을 사용하거나 PlatformTransactionManager를 직접 상속받아서 쓰는 방법이 있다.
  2. RuntimeException 이 던져지면 rollback 이 된다. (그 외의 exception 은 기본적으로 무시)

 

 

 

 

선언적인 트랜젝션

1) Propagation (트랜젝션의 전파)
   <1> PROPAGATION_REQUIRED : 이미 있는 트랜젝션이 있다면 그걸 쓰고, 없다면 새로 만들어 낸다.
   <2> PROPAGATION_MANDATORY : 이미 있는 트랜젝션이 있다면 그걸 쓰고, 없다면
    TransactionRequiredException 을 발생시킨다.
   <3> PROPAGATION_REQUIRES_NEW : 이미 있는 트랜젝션을 잠시 멈추고
    새로운 트랜젝션을 만들어서 수행한다. 새로운 트랜젝션 종료후 기존 트랜젝션이 계속 실행된다.
   <4> PROPAGATION_NESTED : 트랜젝션은 하나만 쓰지만 중간에 savepoint 를 저장하는 방식을 말한다.
    (JDBC 매니져 방식에서만 적용 가능 Hibernate 나 JDO 같은 ORM 에서는 사용불가)
   <5> PROPAGATION_SUPPORTS : 트랜젝션이 없어도 되지만 트랜젝션이 실행되는 중에는 적용을 받는다
    ex) 일일 이체 한도액이 100만원이라고 한다면
     1. 50만원을 이체하는 트랜젝션이 시작
     2. 70만원을 이체하는 SUPPORTS 트랜젝션 시작
     3. 이체한도를 넘기는 결과가 되어 2번의 과정은 롤백이 된다.
     4. 50만원만 이체가 된다.
   <6> PROPAGATION_NOT_SUPPORTED : 트랜젝션이 필요없기 때문에 기존 트랜젝션이 있을 경우
    기존 트랜젝션을 멈추었다가 메소드 실행이 끝난 뒤 트랜젝션을 다시 시작한다.
   <7> PROPAGATION_NEVER : 이미 트랜젝션이 있다면 익셉션을 던져서 메소드 실행을 중지한다.
  

2) Isolation (독립성) : 문서 참고
   독립성이 증가하면 동시성은 감소하고, 데이터의 일관성은 증가한다.
   <1> READ_UNCOMMITTED : 트랜젝션 중 다른 트랜젝션에 의한 커밋되지 않은 데이터도 읽어들일 수 있다.
   <2> READ_COMMITTED : 커밋된 데이터만 읽을 수 있다.
         (다른 트랜젝션에 의한 커밋으로 일어난 변화는 읽어들인다)
   <3> REPEATABLE_READ : 트랜젝션 진행중에는 어떠한 변화점도 읽어들일 수 없다.
         (다른 트랜젝션에 의한 커밋도 상관없이 못 읽어들인다)
   <4> SERIALIZABLE : DB에 하나의 트랜젝션만 허용하는 것으로 하나의 트랜젝션이 실행중에
    다른 트랜젝션이 접근한다면 잠시 중지했다가 기존 트랜젝션이 끝나고 나면 다시 시작한다.
    단, 오라클은 트랜젝션이 중지했다가 시작되는 것이 아니라 ORA-08177 오류를 발생시킨다.
   <5> DEFAULT : DB가 사용하는 isolation 정책 따름
   ※ 문제점 정리
    - Dirty read: 어떤 트랜잭션 T1이 다른 트랜잭션 T2가 아직 커밋하지 않은 데이타를 읽었는데
     T2가 롤백 되는 경우. T1이 읽은 데이타는 dirty.
    - Nonrepeatable read: 어떤 트랜잭션 T1이 계속 해서 같은 데이터를 읽어들이는데 그 사이에
     다른 트랜잭션 T2가 데이타를 수정하면 T1은 같은 데이터를 얻을 수 없게 된다.
    - Phantom read: 어떤 트랜잭션 T1이 계속 데이터를 읽어들이는데 그 사이 다른 트랜잭션 T2가
     새로운 데이타를 추가하면 T1은 전혀 새로운 데이터를 읽어들이게 된다. 마치 귀신처럼.

 

 

 

 

 

 

 

 

 

(참조) https://drunkenamoeba.tistory.com/entry/Spring%EC%9D%B4%EB%9E%80-Spring-MVC

'Programing > Spring' 카테고리의 다른 글

web.xml  (0) 2022.03.04
Eclipse Tomcat Project 작동 순서  (0) 2022.03.04
JdbcTemplate / NamedParameterJdbcTemplate  (0) 2022.03.03
JDBC / JNDI / DBCP  (0) 2022.03.03
Junit  (0) 2022.02.24