spring 이란 ?
스프링은 객체를 담고있는 컨테이너이다. 컨테이너에 저장 될 빈객체와 각 빈객체들간의 의존관계를 XML 파일을 통하여 설정됨.
참고 url
https://docs.spring.io/spring/docs/3.2.18.RELEASE/javadoc-api/
https://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/
spring 설정
MVC 동작
(클라이언트의 요청이 DispatcherServlet에 전달 >>
DispatcherServlet은 HandlerMapping을 사용하여 클라이언트의 요청이 전달될 Controller 객체를 찾는다.(스프링은 기본적으로 5가지의 핸들러 매핑을 제공함, BeanNameUrlHandlerMapping과 DefaultAnnotationHandlerMapping이 기본으로 스프링에 탑재되어 있음) >>
DispatcherServlet은 Controller 객체의 handleRequest() 메소드를 호출하여 클라이언트의 요청을 처리한다. >>
Controller.handleRequest() 메소드는 처리 결과 정보를 담은 ModelAndView 객체를 리턴 한다. >>
DispatcherServlet은 뷰 리졸버(ViewResolver)로부터 처리 결과를 보여줄 View를 구 한다 >>
View는 클라이언트에 전송할 응답을 생성한다.)
MVC 개발 Step
클라이언트의 요청을 받을 DispatcherServlet을 web.xml 파일에 설정한다.
요청 URL과 Controller의 매핑 방식을 설정한다.
Controller의 처리 결과를 어떤 View로 보여줄 지의 여부를 결정하는 ViewResolver를 설정한다.
Controller를 작성한다.
뷰 영역의 코드를 작성한다.
servlet 설정
DispatcherServlet 등장으로 정말 엄청나게 web.xml의 역할이 축소되었음(web.xml에서 servlet을 하나하나 등록하여 매핑 하였음)
HandlerMapping 설정
Info
component-scan / annotation-config / annotation-driven 차이점
<context:component-scan/>
특정 패키지(위에서는 org.controller) 안의 클래스들을 스캔하고 , 빈 인스턴스를 생성한다.
장점중 하나는 @Autowired , @Qualifier 어노테이션을 이해한다는것인데 <context:component-scan> 를 선언했다면 <context:annotation-config> 를 선언할 필요가 없다
DefaultAnnotationHandlerMapping Type레벨에서, AnnotationMethodHandlerAdapter 메서드레벨에서 @RequestMapping을 처리하는데 사용되는데.이 2가지는 DispatcherServlet을 사용할 경우 디폴트로 사용되지만 다른 핸들러맵핑을 합께 사용하려고 하면 수동 지정하여야 함
<mvc:annotation-driven/>
스프링 MVC 컴포넌트들을 그것의 디폴트 설정을 가지고 자동으로 활성화 하기위해 사용된다.
HandlerMapping 와 HandlerAdapter 를 등록을 포함한 클래스패스상에 존재하는것에 기반한 디폴트 작업을 적용한다.
component-scan 과 annotation-driven의 선언에는 어떤한 의존성도 없다.
즉,context:component-scan을 포함해주면 mvc:annotation-driven이 선언 안해준 @Controller / @RequestMapping도 이슈없이 잘 동작한다.
<context:annotation-config/>
어플리케이션 컨텍스트안에 이미 등록된 빈들의 어노테이션 활성화를 위해 사용된다.(그것들이 XML 으로 설정됬는지 혹은 패키지스캐닝을 통한건지는 중요하지 않다)
스프링 컨텍스트에 의해 생성되어 저장된 빈들에 대해서 @Autowired and @Qualifier 어노테이션을 해석할거란 얘기다. (context:component-scan 처럼 scan 기능은 없음)
<context:annotation-config /> 태그를 설정하면 아래의 기능을 각각 설정하는 수고를 덜게 해준다.
- RequiredAnnotationBeanPostProcessor : @Required 어노테이션 처리
- AutowiredAnnotationBeanPostProcessor : @Autowired 어노테이션 처리 (<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
- CommonAnnotationBeanPostProcessor : @Resource, @PostConstruct, @PreDestroy 어노테이션 처리
- ConfigurationClassPostProcessor : @Configuration 어노테이션 처리
설정 (기본 RequestMappingHandlerMapping 설정)
선언하지 않는 방법
<context:component-scan base-package="org.mycode.controller" /> : 패키지 org.mycode.controller 아래의 @Controller중에 @RequestMapping에 선언된 URL과 해당 @Controller 클래스의 메소드와 매핑한다.
<mvc:annotation-driven/>을 선언하는 방법
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping ,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter 이 구성됨
RequestMappingHandlerMapping을 직접 선언하는 방법 (다른 HandlerMapping과 함계 사용할 때 사용.)
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
주요 Handler Mapping 구현 Class
SimpleUrlHandlerMapping : 패턴과 컨트롤러 이름을 비교하여 URL 패턴에 매칭될 경우 지정 컨트롤러 사용
BeanNameUrlHandlerMapping : URL과 일치하는 이름을 갖는 bean을 컨트롤러로 사용
ControllerClassNameHandlerMapping : URL과 매칭되는 클래스 이름을 갖는 bean을 컨트롤러로 사용.
DefaultAnnotationHandlerMapping : @RequestMapping 어노테이션을 이용하여 요청을 처리할 컨트롤러를 구함.
(버전3.1 이후 부터 RequestMappingHandlerMapping 이 기본 HandlerMapping.(DefaultAnnotationHandlerMapping이 deprecated되면서 대체됨)
MessageConverter 설정 (사용할 메시지 컨버터는 AnnotationMethodHandlerAdapter 를 통해 등록한다)
설정
spring 3.1 부터는 <mvc:annotation-driven/>을 사용하면 기본적으로 HttpMessageConverter를 기본적으로 등록되고 AnnotationMethodHandlerAdapter의 messageConverters 프로퍼티로 메지지 컨버터들이 등록됨!
(default 메시지컨버터 와 함께 jaxb2RootElementHttpMessageConverter, MappingJacksonHttpMessageConverter가 등록됨 단, JAXB2와 Jackson 라이브러리 클래스 패스가 존재하는 경우에만 등록된다고 한다.)
메시지 컨버터의 종류 (ref : http://springsource.tistory.com/89)
ByteArrayHttpMessageConverter
StringHttpMessageConverter : 요청 및 응답에서부터 문자열 읽기/쓰기. 기본값으로 이는 text/* 매체 유형을 지원하고 text/plain의 내용 유형(Content-Type)으로 쓴다. (캐릭터셋을 "ISO-8859-1"로 박아놔서 수정해서 사용해야 함)
FormHttpMessageConverter : 요청 및 응답에서부터 양식 데이터 읽기/쓰기. 기본값으로 이는 application/x-www-form-urlencoded 매체 유형을 읽고 데이터를 MultiValueMap<String,String>으로 쓴다.
SourceHttpMessageConverter
Jaxb2RootElementHttpMessageConverter
MarshallingHttpMessageConverter : 마샬러/언마샬러를 사용하여 XML 데이터 읽기/쓰기. 이는 application/xml 매체 유형의 데이터를 변환한다.
MappingJacksonHttpMessageConverter : Jackson의 ObjectMapper를 사용하여 JSON 데이터 읽기/쓰기. 이는 application/json 매체 유형의 데이터를 변환한다.
AllEncompassingFormHttpMessageConverter
AtomFeedHttpMessageConverter : ROME의 피드 API를 사용하여 ATOM 피드 읽기/쓰기. 이는 application/atom+xml 매체 유형의 데이터를 변환한다.
RssChannelHttpMessageConverter : ROME의 피드 API를 사용하여 RSS 피드 읽기/쓰기. 이는 application/rss+xml 매체 유형의 데이터를 변환한다.
ViewResolver 설정
Spring Bean
Bean 객체 범위
스프링 컨테이너 내에서 빈 객체는 싱글턴
아래 코드를 를 통해 생성된 testDao는 동일한 객체이다 (bean : <bean name="testDao" class="com.ljw.TestDao"/>)
TestDao testDao1 = (TestDao)applicationContext.getBean("testDao");
TestDao testDao2 = (TestDao)applicationContext.getBean("testDao");
bean scope를 명시하여 서로다른 객체로 생성이 가능
<bean name="testDao" class="com.ljw.TestDao" scope="protytype" /> --> bean의 scope 속성값에 설정 하여 사용
scope="singleon" : 기본값이며 스프링 컨테이너당 하나의 빈 객체 생성
scope="prototype" : 빈은 사용할때마다 새로운 객체 생성
scope="request" : http 요청마다 새로운 객체 생성(WebApplicationContext에서 사용)
scope="session" : 세션마다 새로운 객체 생성(WebApplicationContext에서 사용)
일반적인 bean 선언 : <bean id="testBean" class="com.ljw.TestBean" />
id : spring container 에서 유일하게 실별할수 있는 이름 (id 대신 name 속성을 사용할수 있음)
class : 해당 bean의 full path
생성자를 통한 bean 설정
<bean id="testService" class="com.ljw.Service">
<constructor-arg>
<ref bean="testDao"/>
</constructor-arg>
</bean>
<bean id="testDao" class="com.ljw.TestDao"/>
<bean id="testService" class="com.ljw.Service">
<constructor-arg ref="testDao"/>
</bean>
ref : reference(즉 testDao id(혹은 name)를 갖는 bean을 생성자의 인자로 넘겨주겠다는 의미)
생성자에 값을 넘겨줄 때
<bean id="testService" class="com.ljw.Service">
<constructor-arg>
<value> 10 </value>
</constructor-arg>
</bean>
<bean id="testService" class="com.ljw.Service">
<constructor-arg value="10"/>
</bean>
property bean 설정 (setXXX 함수 를 이용하여 bean 설정)
property는 TestService class의 setTestDao method를 의미하며 TestService class의 setTestDao 메소드를 호출하면서 인자 값으로 ImplTestDao 객체를 넘겨준다는 의미
<bean id="testServcie" class="con.ljw.TestService" >
<property name="testDao">
<ref bean="implTestDao"/>
</property>
</bean>
<bean id="implTestDao" class="con.ljw.ImplTestDao" />
props : java.util.properties 클래스로 key, value를 string type으로만 갖는다.
아래 예는 SimpleUrlHandlerMapping 클랙스의 setMappings 메소드를통해 properties 객체를 생성하고
해당 properties 객체는 key="/login/login.mw", value = loginController를 갖고 있게된다.
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/login/login.mw">loginController</prop>
</props>
</property>
</bean>
Annotation (ref : http://noritersand.tistory.com/156#@ResponseBody)
DI (Dependency Injection)를 이용한 bean 생성은 내부적으로 싱글톤 패턴을 이용해 객체를 인스턴스화 합니다.
@Bean vs @Component : @Bean어노테이션과 @Componet어노테이션 둘다 Spring IOC Container에 Bean을 등록하도록 메타데이터를 기입하는 어노테이션이다.
@Bean어노테이션의 경우 직접 제어가 불가능한 외부 라이브러리등을 Bean으로 만들려 할 때 사용된다.(메소드 레벨에서 선언)
@Component어노테이션의 경우 개발자가 직접 작성한 Class를 Bean으로 등록하기 위한 어노테이션이다.(클래스 레벨에서 선언)
@Controller : Controller 객체임을 선언
@Controller로 등록된 클래스 파일에 대한 bean을 자동으로 생성
Controller로 사용하고자 하는 클래스에 @Controller 어노테이션을 명시하면 component-scan으로 자동 등록된다.
@Service : Service 객체임을 선언 (서비스 계층의 Business Object 에서 사용)
@Repository : DAO (Data Access Object)임을 선언 (@Repository는 DAO(Data Access Object)에서 사용)
@Resource : 필요한 빈(bean)을 수동으로 등록 즉, 리소스 접근을 위한 선언
@RequestMapping : 요청 URL 맵핑
@RestController : RESTful 웹서비스 컨트롤러 선언 (spring 4의 새로운 annotation으로 @Controller 와 @ResponseBody의 축약형)
@RequestParam : URL 매개변수를 메소드로 삽입한다.
@RequestHeader : 특정 HTTP 헤더를 메소드로 삽입한다.
@RequestBody : HTTP 요청 본문을 메소드로 삽입한다.
@ResponseBody : HTTP 응답 본문으로 내용이나 오브젝트를 리턴한다. View를 통해서 출력되는 것이 아니라 Http Response Body에 직접 쓰여지게 된다.
@Autowired : Spring Framework에서 지원하는 의존주입 용도의 어노테이션이다.말 그대로 타입으로 참조할 빈을 찾았을 때 Injection 일어난다. (여러개 검색되었을때 @Qualifier("class명") 어노테이션을 사용하여 구분 하여 사용함)
@Autowired가 지정된 프로퍼티는 모두 설정되어야 한다. 만약 스프링이 연결할 빈을 찾지 못하면 예외처리가 발생되고, 이 경우를 대비하여 @Autowired(Required=false) 애트리뷰트를 false로 설정하면 스프링이 호환되는 빈을 찾지 못하여도, 예외처리 없이 프로퍼티를 설정하지 않은 채로 남겨둘 것이다.
@Resource : bean name으로 의존주입을 하고자 하는 경우 사용된다. 기본적으로 스프링은 해당 프로퍼티와 일치하는 빈을 찾을 것이고, 혹은 name 속성을 이용해 명시적으로 빈의 이름을 설정할 수 있다.
@RunWith : JUnit 프레임워크의 테스트 실행 방법을 확장할 때 사용하는 애노테이션이다.
(SpringJUnit4ClassRunner라는 JUnit용 테스트 컨텍스트 프레임워크 확장 클래스를 지정해주면 JUnit이 테스트를 진행하는 중에 테스트가 사용할 애플리케이션 컨텍스트를 만들고 관리하는 작업을 진행해준다.)
@ContextConfiguration : 자동으로 만들어줄 애플리케이션 컨텍스트의 설정파일위치를 지정
@SpringApplicationConfiguration : ApplicationContext를 선택하여 테스트를 할 수 있다. 이에 따라 클래스 멤버에 애플리케이션 컨텍스트의 빈을 주입하여 테스트에 사용할 수 있다. (@Autowired, @Qualifier, @Resource)
@WebIntegrationTest : 실제 웹 애플리케이션이 구동되는 환경과 동일하게 HTTP 요청 테스트가 가능하다. TestRestTemplate 클래스를 사용한다.
@ActiveProfiles : 테스트 실행시 적용될 프로파일을 적용할 수 있다.
@Test : 테스트 메써드로 선언되어 메써드 단위 테스트가 가능해진다.
@FixMethodOrder: 테스트 메써드 간의 실행 순서를 결정할 수 있다. JUnit에서는 테스트 순서가 임의로 진행된다.
(MethodSorters.NAME_ASCENDING은 메써드의 이름 순으로 실행 순서를 결정하겠다는 의미)
@SuppressWarning : 이클립스 컴파일러가 알려주는 노란색 경고 표시를 없애주는 역할을 한다.
all : 모든 경고를 표시 안함
cast : 캐스트 연산자 관련 경고를 표시 안함
dep-ann : 사용하지 말아야 할 주석 관련 경고를 표시 안함
deprecation : 사용하지 말아야 할 메소드 관련 경고를 표시 안함
fallthrough : switch문에서의 break 누락 관련 경고를 표시 안함
finally : 반환하지 않는 finally 블럭 관련 경고를 표시 안함
null : null 분석 관련 경고를 표시 안함
rawtypes : 제네릭을 사용하는 클래스 매개 변수가 불특정일 때의 경고를 표시 안함
unchecked : 검증되지 않은 연산자 관련 경고를 표시 안함
unused : 사용하지 않는 코드 관련 경고를 표시 안함
폴더 Info
Spring MVC Template
target폴더는 우리가 프로젝트를 모두 완성한 뒤, 작성한 class 파일들을 빠르게 jar로 배포할 수 있도록 maven에서 만든 폴더이다.