@Component
패키지: org.springframework.stereotype
버전: spring 2.5
설정 위치: 클래스 선언부 앞
<context:component-scan> 태그를 설정파일에 추가하면 해당 어노테이션이 적용된 클래스를 빈으로 등록하게 된다. 범위는 디폴트로 singleton이며 @Scope를 사용하여 지정할 수 있다.
사용하려면 XML 설정파일에 <context:component-scan>을 정의하고 적용할 기본 패키지를 base-package 속성으로 등록한다.
context:annotation-config 태그는 어노테이션과 관련해서 다음의 BeanPostProcessor를 함께 등록 한다.
- @Required(RequiedAnnotationBeanPostProcessor)
- @Autowired(AutowiredAnnotationBeanPostProcessor)
- @Resource, @PostConstruct, @PreDestory(CommonAnnotationBeanPostProcessor)
- @Configuration(ConfigurationClassPostProcessor)
- 그 외 Repository, Service, Controller 포함
예를 들어 다음처럼 설정하면:
<context:component-scan base-package="xxx"/>
xxx 패키지 하위에 @Component로 선언된 클래스를 bean으로 자동 등록한다. bean의 이름은 해당 클래스명(첫글자는 소문자)이 사용된다.
<context:component-scan /> 요소에는 scoped-proxy 속성이 존재 한다. scoped-proxy는 <aop:scoped-poxy/>처럼 WebApplicationContext 에서만 유효하며 "session", "globalSession", "request" 이외의 scope는 무시 되며 아래의 3가지 값을 설정 할 수 있다.
- no: proxy를 생성하지 않는다.(기본값)
- interfaces: JDK Dynamic Proxy를 이용한 Proxy 생성
- targetClass: 클래스에 대해 프록시를 생성(CGLIB를 이용한 Proxy 생성)
@Component @Scope("prototype") // 생략하면 싱글톤 public class Test { ..... }
CGLIB
기존의 자바 클래스파일로부터 자바의 소스코드를 동적으로 생성하는 라이브러리(자바 소스 변경)
http://sourceforge.net/projects/cglib/
스캔 대상 클래스 범위 지정하기
<context:include-filter> 태그와 <context:exclude-filter> 태그를 사용하면 자동 스캔 대상에 포함시킬 클래스와 포함시키지 않을 클래스를 구체적으로 명시할 수 있다.
<context:component-scan base-package="spring.demo" scoped-proxy="no"> <context:include-filter type="regex" expression="*HibernateRepository"/> <context:exclude-filter type="aspectj" expression="..*IBatisRepository"/> </context:component-scan>
위와 같이 <context:include-filter> 태그와 <context:exclude-filter> 태그는 각각 type 속성과 expresseion 속성을 갖는데, type 속성에 따라 expression 속성에 올 수 있는 값이 달라진다. type 속성에 입력가능한 값은 다음과 같다:
- annotation: 클랙스에 지정한 어노테이션이 적용됐는지의 여부. expression 속성에서는 "org.example.SomeAnnotation"와 같은 어노테이션 이름을 입력한다.
- assignable: 클래스가 지정한 타입으로 할당 가능한지의 여부. expression 속성에는 "org.exampleSomeClass" 와 같은 타입 이름을 입력한다.
- regex: 클래스 이름이 정규 표현식에 매칭되는 지의 여부. expression 속성에는 "org\.example\.Default.*" 와 같이 정규표현식을 입력한다.
- aspectj: 클래스 이름이 AspectJ 의 표현식에 매칭되는 지의 여부. expression 속성에는 "org.example..*Service+" 와 같이 AspectJ 의 표현식을 입력한다.
@Required
패키지: org.springframework.beans.factory.annotation
버전: spring 2.0
설정 위치: setter 메서드 앞
Required 어노테이션은 필수 프로퍼티임을 명시하는 것으로 필수 프로퍼티를 설정하지 않을 경우 빈 생성시 예외를 발생시킨다.
import org.springframework.beans.factory.annotation.Required public class TestBean { @Required private TestDao testDao; public void setTestDao(TestDao testDao) { this.testDao = testDao; } }
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanpostProcessor"/> <bean name="testBean" class="han.test.TestBean"> <property name="testDao" ref="testDao"/> <!-- @Required 어노테이션을 적용하였으므로 설정하지 않으면 예외를 발생시킨다. --> </bean>
RequiredAnnotationBeanPostProcessor 클래스는 스프링 컨테이너에 등록된 bean 객체를 조사하여 @Required 어노테이션으로 설정되어 있는 프로퍼티의 값이 설정되어 있는지 검사한다.
사용하려면 <bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor" /> 클래스를 빈으로 등록시켜줘야 하지만 이를 대신하여 <context:annotation-config> 태그를 사용해도 된다:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> <context:annotation-config/> </beans>
@Autowired
패키지: org.springframework.beans.factory.annotation
버전: spring 2.5
설정 위치: 생성자, 필드, 메서드(setter메서드가 아니여도 된다) 앞
의존관계를 자동설정할 때 사용하며 타입을 이용하여 의존하는 객체를 삽입해 준다. 그러므로 해당 타입의 빈객체가 존재하지 않거나 또는 2개 이상 존재할 경우 스프링은 예외를 발생시키게 된다.
options:
- required: Autowired 어노테이션을 적용한 프로퍼티 중 반드시 설정할 필요가 없는 경우에 false값을 주어 프로퍼티가 존재하지 않더라도 스프링이 예외를 발생하지 않도록 한다. 기본값은 TRUE. ex) @Autowired(required=false)
사용하려면 <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" /> 클래스를 빈으로 등록시켜줘야 한다. 해당 설정 대신에 <context:annotation-config> 태그를 사용해도 된다.
@Autowired를 적용할 때 같은 타입의 빈이 2개 이상 존재하게 되면 예외가 발생하는데, Autowired도 이러한 문제가 발생한다. 이럴 때 @Qualifier를 사용하면 동일한 타입의 빈 중 특정 빈을 사용하도록 하여 문제를 해결할 수 있다.
@Autowired @Qualifier("test") private Test test;
@Qualifier
패키지: org.springframework.beans.factory.annotation
버전: spring 2.5
설정 위치: @Autowired 어노테이션과 함께 사용된다.
qualifier 어노테이션은 @Autowired의 목적에서 동일 타입의 빈객체가 존재시 특정빈을 삽입할 수 있게 설정한다. @Qualifier("mainBean")의 형태로 @Autowired와 같이 사용하며 해당 <bean>태그에 <qualifire value="mainBean" /> 태그를 선언해주어야 한다. 메서드에서 두개이상의 파라미터를 사용할 경우는 파라미터 앞에 선언해야한다.
options:
- name: alias명
사용하려면 동일타입의 빈객체 설정에서 <qualifier value="[alias명]" />를 추가해 준다.
<bean id="user2" class="com.sp4.UserImpl"> <property name="name" value="스프링"/> <property name="age" value="20"/> <property name="tel" value="000-0000-0000"/> </bean> <bean id="userService1" class="com.sp4.UserService"/>
public class UserService { @Autowired @Qualifier("user2") private User user; public String result() { return user.getData(); } }
@Resource
자바 6 및 JEE5에 추가된 것으로 어플리케이션에서 필요로 하는 자원을 자동 연결할 때 사용 한다. 스프링 2.5 부터 지원하는 어노테이션으로 스프링에서는 의존하는 빈 객체를 전달할 때 사용한다.
@Autowired와 흡사하지만 @Autowired는 타입으로(by type), @Resource는 이름으로(by name)으로 연결한다는 점이 다르다.
options:
- name: 자동으로 연결될 빈객체의 이름을 입력한다. ex) @Resource(name="testDao")
사용하려면 <bean class="org.springframework.beans.factory.annotation.CommonAnnotationBeanPostProcessor"/> 클래스를 빈으로 등록시켜줘야 한다. 해당 설정 대신에 <context:annotation-config> 태그를 사용해도 된다.
<beans> <!-- 기타 설정 생략 --> <context:annotation-config/> <bean id="user2" class="com.test.UserImpl" p:data="65536"/> </beans>
public class UserService { @Resource(name="user2") private User user; //UserImpl user2 = new UserImpl(); //User user = user2; public void setUser(User user) { this.user = user; } public String result() { return user.getData(); } }
@Scope
패키지: org.springframework.beans.factory.annotation
설정: prototype, singleton, request, session, globalSession
스프링은 기본적으로 빈의 범위를 "singleton" 으로 설정한다. "singleton" 이 아닌 다른범위를 지정하고 싶다면 @Scope 어노테이션을 이용하여 범위를 지정한다.
@Component @Scope(value="prototype") public class Worker {}
@Component @Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS) public class Worker {}
@PostConstruct
패키지: javax.annotation
버전: jdk1.6, spring 2.5
설정 위치: 초기화 작업 수행 메서드 앞
의존하는 객체를 설정한 이후에 초기화 작업을 수행하기 위해 사용한다. 스프링에 의해 인스턴스가 생성된 후 어노테이션이 적용된 메서드가 호출된다. 사용하려면 CommonAnnotationBeanPostProcessor 클래스를 빈으로 등록시켜줘야 한다. <context:annotation-config> 태그로 대신할 수 있다.
@PostConstruct public void init() { System.out.println("객체 생성 후 내가 먼저 실행된다."); }
@PreDestroy
패키지: javax.annotation
버전: jdk1.6, spring 2.5
설정 위치: 해당 작업 메서드 앞
컨테이너에서 객체를 제거하기 전에 해야할 작업을 수행하기 위해 사용한다.
사용하려면 CommonAnnotationBeanPostProcessor 클래스를 빈으로 등록시켜줘야 한다. <context:annotation-config> 태그로 대신할 수 있다.
@Inject
SR-330 표준 Annotation으로 Spring 3 부터 지원하는 Annotation이다. 특정 Framework에 종속되지 않은 어플리케이션을 구성하기 위해서는 @Inject를 사용할 것을 권장한다. @Inject를 사용하기 위해서는 클래스 패스 내에 JSR-330 라이브러리인 javax.inject-x.x.x.jar 파일이 추가되어야 함에 유의해야 한다.
@Service
@Service를 적용한 Class는 비지니스 로직이 들어가는 Service로 등록이 된다. Controller에 있는 @Autowired는 @Service("xxxService")에 등록된 xxxService와 변수명이 같아야 하며 Service에 있는 @Autowired는 @Repository("xxxDao")에 등록된 xxDao와 변수명이 같아야 한다.
@Service("helloService") public class HelloServiceImpl implements HelloService { @Autowired private HelloDao helloDao; public void hello() { System.out.println("HelloServiceImpl :: hello()"); helloDao.selectHello(); } }
helloDao.selectHello(); 와 같이 @Autowired를 이용한 객체를 이용하여 Dao 객체를 호출한다:
@Service("test2.testService") //괄호 속 문자열은 식별자를 의미한다. //괄호를 생략할 경우 클래스명 그대로 사용한다. //따라서 ,같은 클래스명이 존재 할 시 같은 식별자가 생성되기때문에 에러가 발생한다. public class TestService { public String result(int num1, int num2, String oper) { String str = null; if (oper.equals("+")) { //... return str; } } }
@Resouce로 연결
@Resource(name="test2.testService") //name에 필요한 것은 @Service("test2.testService") <- 여기서 괄호 속 문자열, 즉 식별자 private TestService service; //TestService service = new TestService(); 라고 하는것과 같은 식 @RequestMapping(value="/test2/oper.action", method={RequestMethod.GET}) public String form() throws Exception { return "test2/write"; }
@Repository
패키지: org.springframework.stereotype
버전: spring 2.0
@Repository는 일반적으로 DAO에 사용되며 DB Exception을 DataAccessException으로 변환한다.
@Repository("bbs.boardDAO") public class BoardDAO { private SqlSession sqlSession; public int insertBoard(Board dto) throws Exception { ... } }
public class BoardServiceImpl implements BoardService { @Resource(name="bbs.boardDAO") private BoardDAO dao; public int insertBoard(Board dto){} }
@Controller
패키지: org.springframework.stereotype
버전: spring 2.5
spring MVC의 Controller 클래스 선언을 단순화시켜준다. 스프링 컨트롤러, 서블릿을 상속할 필요가 없으며, @Controller로 등록된 클래스 파일에 대한 bean을 자동으로 생성해준다.
Controller로 사용하고자 하는 클래스에 @Controller 어노테이션을 명시하면 component-scan으로 자동 등록된다.
<context:component-scan base-package="com.*"/>
|
cs |
package com.test;
import org.springframework.stereotype.Controller;
@Controller
public class SpringTest {
//...
}
|
cs |
컨트롤러 메서드의 파라미터 타입
파라미터 타입 | 설명 |
HttpServletRequest, HttpServletResponse, HttpSession | Servlet API |
java.util.Locale | 현재 요청에 대한 Locale 정보 |
InputStream, Reader | 요청 컨텐츠에 직접 접근할 때 사용 |
OutputStream, Writer | 응답 컨텐츠를 생성할 때 사용 |
@PathVariable 어노테이션 적용 변수 | URL 템플릿 변수에 접근할 때 사용 |
@RequestParam 어노테이션 적용 변수 | HTTP 파라미터와 매핑 |
@RequestHeader 어노테이션 적용 변수 | HTTP 헤더 매핑 |
@CookieValue 어노테이션 적용 변수 | HTTP 쿠키 매핑 |
@RequestBody 어노테이션 적용 변수 | HTTP RequestBody에 접근할 때 사용. HttpMessage Converter를 이용해 RequestBody 데이터를 해당 타입으로 변환한다. |
Map, Model, ModelMap | 뷰에 전달할 모델 데이터를 설정할 때 사용 |
커맨드 객체 | HTTP 요청 파라미터를 저장한 객체, 기본적으로 클래스 이름을 모델명으로 사용. |
Errors, BindingResult | HTTP 요청 파라미터를 커맨드 객체에 저장한 결과. 커맨드 객체를 위한 파라미터 바로 다음에 위치한다. |
SessionStatus | 폼 처리를 완료 했음을 처리하기 위해 사용. @SessionAttribute를 명시한 session 속성을 제거하도록 이벤트를 발생시킨다. |
컨트롤러 메서드의 파라미터 타입 사용 예시 보기
컨트롤러 메서드의 리턴 타입
리턴 타입 | 설명 |
ModelAndView | 뷰 정보 및 모델 정보를 담고 있는 ModelAndView 객체 |
Model | 뷰에 전달할 객체 정보를 담고 있는 Model을 리턴한다. 이때 뷰 이름은 요청 URL로부터 결정된다. (RequestToViewNameTranslator를 통해 뷰 결정) |
Map, ModelMap | 뷰에 전달할 객체 정보를 담고 있는 Map 혹은 ModelMap을 리턴한다. 이때 뷰 이름은 요청 URL로부터 결정된다. (RequestToViewNameTranslator를 통해 뷰 결정) |
String | 뷰 이름을 리턴한다. |
View 객체 | View 객체를 직접 리턴. 해당 View 객체를 이용해서 뷰를 생성한다. |
void | 메서드가 ServletResponse나 HttpServletResponse 타입의 파라미터를 갖는 경우 메서드가 직접 응답을 처리한다고 가정한다. 그렇지 않을 경우 요청 URL로부터 결정된 뷰를 보여준다. (RequestToViewNameTranslator를 통해 뷰 결정) |
@ResponseBody 어노테이션 적용 | 메서드에서 @ResponseBody 어노테이션이 적용된 경우, 리턴 객체를 HTTP 응답으로 전송한다. HttpMessageConverter를 이용해서 객체를 HTTP 응답 스트림으로 변환한다. |
@RequestMapping
URL을 컨트롤러의 메서드와 매핑할 때 사용하는 스프링 프레임워크의 어노테이션이다.
클래스나 메서드 선언부에 @RequestMapping과 함께 URL을 명시하여 사용한다. URL외에도 HTTP 요청 메서드나 헤더값에 따라 매핑되도록 -0=옵션을 제공한다. 메서드 레벨에서 정의한 @RequestMapping은 타입 레벨에서 정의된 @RequestMapping의 옵션을 상속받는다.
참고로, 메서드 내에서 viewName을 별도로 설정하지 않으면 @RequestMapping의 path로 설정한 URL이 그대로 viewName으로 설정된다.
options
path(혹은 value)
요청된 URL에 따라 매핑한다.
path = "some-url.action"
path = { "some-url1, some-url2" }
매핑할 URL은 하나 이상 지정할 수 있다.
@RequestMapping(path = { "/addMovie.do", "/updateMovie.do" })
public String myMethod() {
// "/addMovie.do", "/updateMovie.do" 두 URL 모두 처리한다.
}
|
cs |
디폴트 속성이기 때문에 속성명을 생략하고 @RequestMapping("/addMovie.do")와 같은 방식으로 사용할 수 있다.
method
GET, POST, PUT, DELETE같은 HTTP Request method에 따라 매핑을 결정한다. 값은 enum 타입인 RequestMethod다.
@RequestMapping(method = RequestMethod.POST)
public String myMethod() {
// ...
}
|
cs |
params
요청된 파라미터에 따라 매핑한다.
params = { "someParam1=someValue", "someParam2" }
params = "!someExcludeParam"
아래처럼 설정하면 요청 파라미터에 param1과 param2 파라미터가 존재해야하고 param1의 값은 'a'이어야하며, myParam이라는 파라미터는 존재하지 않아야한다.
@RequestMapping(params = {"param1=a", "param2", "!myParam"})
public String myMethod() {
// ...
}
|
cs |
headers
특정 헤더의 값에 따라 매핑한다.
headers = "someHader=someValue"'
headers = "someHader"', 'headers="!someHader"
와일드 카드 표현(*)도 지원한다.
아래처럼 설정하면 HTTP Request에 Content-Type 헤더 값이 "text/html", "text/plain" 모두 매칭이 된다.
@RequestMapping(path = "/movie.do", headers = "content-type=text/*")
public String myMethod() {
// ...
}
|
cs |
produces TODO
@RequestMapping(path = "...", produces = "application/json")
@RequestBody
public HashMap<String, String> testMethod(Model model) {
HashMap<String, String> map = new HashMap<String, String>();
map.put("code", "0");
return map;
}
|
cs |
example
@Controller
@RequestMapping("/test/*")
public class SampleController1 {
@RequestMapping(method = RequestMethod.GET, path = "go")
public returntype getMethodName() {
// ...
}
@RequestMapping(method = RequestMethod.POST, path = "go2")
public returntype getMethodName2() {
// ...
}
}
@Controller
@RequestMapping("/main.action")
public class SampleController2 {
@RequestMapping(method=RequestMethod.GET)
public String method() {
return ".mainLayout";
}
}
@Controller
public class SampleController3 {
@RequestMapping("/main.action")
public returntype m01() {
// ...
}
}
|
cs |
@RequestParam
required
- spring framework 2.5 or higher
RequestParam annotation은 key=value 형태로 화면에서 넘어오는 쿼리스트링 혹은 폼 데이터를 메서드의 파라미터로 지정한다. 대체로 파라미터의 개수가 적을때 사용한다.
method( @RequestParam( PARAM ) Obj )
method( @RequestParam Map)
- PARAM: 전달되는 파라미터의 이름을 지정한다. 이름 외에 기본값(defaultValue), 필수여부(required)를 설정할 수 있다. 값이 할당될 변수의 타입이 Map 혹은 MultiValueMap일 땐 명시하지 않는다.
- Obj: PARAM으로 지정된 이름과 일치하는 파라미터의 값을 할당할 변수. 보통 String 타입을 선언하지만 넘 어온 값이 반드시 숫자일 경우에 한해서 int 등의 숫자 타입도 가능하다.
이름과 변수를 지정하는 방식
아래에서 xxx/editBlog.do?blogId=3 과 같이 접근할 때, editBlogHandler 메서드의 파라미터인 blogId에는 3이 셋팅된다. 필수 요건이 아닐 경우, @RequestParam(value="id", required="false")와 같이 옵션을 주고 사용할 수 있다.
@Controller public class BlogController { @RequestMapping("/editBlog") public ModelMap editBlogHandler(@RequestParam("blogId") int blogId) { blog = blogService.findBlog(blogId); return new ModelMap(blog); } // ... }
@RequestMapping(value="/...", method={RequestMethod.GET, RequestMethod.POST}) public String submit(HttpServletRequest req, @RequestParam(value="num1") int num1, @RequestParam(value="num2") int num2, @RequestParam(value="oper") String oper) throws Exception { // value: request parameter의 이름 // 생략 } //@RequestParam 어노테이션이 적용된 파라미터는 기본적으로 필수 파라미터이다. //따라서, 명시한 파라미터가 존재하지 않을 경우 400 에러가 발생한다. //여기서 파라미터에 값이 있을수도 없을수도 있는 로직을 구현하려면 다음처럼 작성한다. @RequestMapping(value="/...", method={RequestMethod.GET, RequestMethod.POST}) public String submit(HttpServletRequest req, @RequestParam(value="num1", defaultValue = "0") int num1, @RequestParam(value="num2", defaultValue = "0") int num2, @RequestParam(value="oper", required=false) String oper) throws Exception { // 생략 }
Map 방식
값을 할당할 변수의 타입을 Map 혹은 MultiValueMap으로 사용하는 방법.
@RequestMapping("/faqDetail") public String faqDetail(@RequestParam HashMap<String, String> map) { String searchValue = map.get("searchValue"); // req.getParameter("searchValue") 와 같다. return "/board/faq/faqDetail"; }
@SessionAttributes
SessionAttribute annotation은 세션상에서 model의 정보를 유지하고 싶을 경우 사용한다.
@Controller @SessionAttributes("blog") public class BlogController { // 중간생략 @RequestMapping("/createBlog") public ModelMap createBlogHandler() { blog = new Blog(); blog.setRegDate(new Date()); return new ModelMap(blog); } // 중간생략 }
@SessionAttributes는 model로 할당된 객체 중 지정된 이름과 일치하는 객체를 세션 속성에도 추가한다.
@SessionAttributes("someSessionAttr") class ExampleController2 { @RequestMapping("/test") public ModelAndView drawTest(ModelAndView view, @ModelAttribute("someSessionAttr") String someSessionAttr) { view.addObject("someSessionAttr", someSessionAttr); return view; } }
@RequestBody
@RequestBody 어노테이션이 적용된 파라미터는 HTTP Request body의 내용이 전달된다.
참고: http://java.ihoney.pe.kr/283
@RequestMapping(value="/test") public void penaltyInfoDtlUpdate(@RequestBody String body, HttpServletRequest req, HttpServletResponse res, Model model, HttpSession session) throws Exception { System.out.println(body); }
@ResponseBody
참고: http://ismydream.tistory.com/140
클라이언트에 JSON 형식의 값을 응답할 때 유용하다. 메서드에 @ResponseBody를 적용한 후 문자열을 리턴하면 그 값은 HTTP response header가 아니라 HTTP response body에 쓰여진다. 객체를 넘길경우 스프링에 내장된 JACKSON에 의해 문자열로 변환될 것이다.
또한 @ResponseBody가 적용된 컨트롤러는 context에 설정된 resolver를 무시한다.
@RequestMapping("/getVocTypeList") @ResponseBody public ArrayList<Object> getVocTypeList() throws Exception { HashMap<String, Object> vocData = gvocInf.searchVocTypeList(); return (ArrayList<Object>) vocData.get("data"); }
@PathVariable
URL의 일부를 파라미터 혹은 변수로 사용한다.
package com.sp.ex; @Controller("ex.exController") public class ExController{ @RequestMapping(value="/blog/{userId}/main.action", method=RequestMethod.GET) public String main(HttpServletRequest req , @PathVariable String userId) throws Exception { req.setAttribute("userId", userId); return "restful/result"; } }
'Programming > [Spring]' 카테고리의 다른 글
[Spring] Maven (0) | 2019.06.12 |
---|---|
[Spring] Springboot (0) | 2019.06.05 |
[Spring] 스프링 어드바이스 종류(Spring Advice) (0) | 2018.05.17 |
[Spring] 스프링 빈 스코프(Spring Bean Scope) (0) | 2018.05.16 |
[Spring] Spring 처음 시작 (0) | 2018.05.15 |