posted by 귀염둥이채원 2019. 3. 27. 21:30

# Annotation이란?
- @를 이용한 주석, 자바코드에 주석을 달아 특별한 의미를 부여한 것
  (참고로 클래스, 메소드, 변수 등 모든 요소에 선언이 가능)
- 메타데이터(실제데이터가 아닌 Data를 위한 데이터) 라고도 불리고 JDK5부터 등장
컴파일러가 특정 오류를 억제하도록 지시하는 것과 같이 프로그램 코드의 일부가 아닌 
  프로그램에 관한 데이터를 제공, 코드에 정보를 추가하는 정형화된 방법.
ex) @Repository, @Service, @Controller, @Autowired, @Resource

# Annotation이 나온 이유
IT가 발전하면서 프로그램의 규모가 방대해지면서 XML이 가지는 설정정보의 양이 많아진다
--> Annotation은 직관적인 메타데이터 설정이 가능. 왜냐하면 소스코드와 같이 쓰기 때문에 
      (소스코드와 메타데이터가 결합되는 형태)
--> 시스템 전반에 영향을 주는 메타데이터는 XML로 설정하여 코드로부터 독립적으로 분리되는 것이 바람직하다. 

그래서 변경사항이 있을 때 유지보수성이 높아진다. 
설계시 확정되는 부분은 Annotation 기반 설정으로 개발의 생산성을 향상 시키는 것이 바람직함

# Annotation 사용시 장점
데이터에 대한 유효성 검사조건을 어노테이션을 사용하여 Model 클래스에 직접 명시함으로써 
해당 데이터들에 대한 유효 조건을 쉽게 파악할수 있게되며, 코드의 양도 줄어든다. 
(코드가 깔끔해지고, 어노테이션의 재사용도 가능해진다. )

########################################
# 주요 Annotation
########################################
@SpringBootApplication
- @Configuration, @EnableAutoConfiguration, @ComponentScan 3가지를 하나의 애노테이션으로 합친 것이다.

# @ComponentScan
- @Component와 @Service, @Repository, @Controller, @Configuration이 붙은 클래스 Bean들을 찾아서 Context에 bean등록을 해주는 Annotation
ApplicationContext.xml에  이런식으로 xml에 bean을 직접등록하는 방법도 있고 위와 같이 애노테이션을 붙여서 하는 방법도 있음

base-package를 넣으면 해당 패키지 아래에 있는 컴포넌트들을 찾고 그 과정을 spring-context-버전(4.3.11.RELEASE).jar에서 처리한다.
@Component로 다 쓰지 왜 굳이 @Repository, @Service, @Controller등을 사용하냐면 예를들어 @Repository는 DAO의 메소드에서 발생할 수 있는 unchecked exception들을 스프링의 DataAccessException으로 처리할 수 있기 때문이다. 또한 가독성에서도 해당 애노테이션을 갖는 클래스가 무엇을 하는지 단 번에 알 수 있다.

xxx 패키지 하위에 @Component로 선언된 클래스를 bean으로 자동등록(bean 이름 : 해당클래스 이름, 첫글자 소문자)

@EnableAutoConfiguration
- 스프링 애플리케이션 컨텍스트를 만들 때 자동으로 설정하는 기능을 켠다.
classpath의 내용에 기반해서 자동 생성해준다. 만약 tomcat-embed-core.jar가 존재하면 톰캣 서버가 setting된다.

@Configuration
- Configuration을 클래스에 적용하고 @Bean을 해당 클래스의 메소드에 적용하면 @Autowired로 빈을 부를 수 있다.

@Required
- setter 메서드에 적용해주면 빈 생성시 필수 프로퍼티 임을 알린다.

@Qualifier("id123")
- @Autowired와 같이 쓰이며, 같은 타입의 빈 객체가 있을 때 해당 아이디를 적어 원하는 빈이 주입될 수 있도록 하는 애노테이션
(같은 타입이 존재하는 경우 ex) 동물, 원숭이, 닭, 개, 돼지)

@Resource
- @Autowired와 마찬가지로 빈 객체를 주입해주는데 차이점은 Autowired는 타입으로, Resource는 이름으로 연결해준다.

@PostConstruct, @PreConstruct
- 의존하는 객체를 생성한 이후 초기화 작업을 위해 객체 생성 전/후에(pre/post) 실행해야 할 메소드 앞에 붙인다.

@PreDestroy
- 객체를 제거하기 전(pre)에 해야할 작업을 수행하기 위해 사용한다.

@PropertySource
- 해당 프로퍼티 파일을 Environment로 로딩하게 해준다.
클래스에 @PropertySource("classpath:/settings.properties")라고 적고 클래스 내부에 @Resource를 Environment타입의 멤버변수앞에 적으면 매핑된다.

@ConfigurationProperties
- yaml파일 읽는다. default로 classpath:application.properties 파일이 조회된다.
속성 클래스를 따로 만들어두고 그 위에 (prefix="mail")을 써서 프로퍼티의 접두사를 사용할 수 있음

mail.host = mailserver@mail.com
mail.port = 9000
mail.defaultRecipients[0] = admin@mail.com
mail.defaultRecipients[1] = customer@mail.com

@Value
- properties에서 값을 가져와 적용할 때 사용한다.

@Value("${value.from.file}")
private String valueFromFile; 이라고 구성되어 있으면 value.from.file의 값을 가져와서 해당 변수에 주입해준다.

@RequestMapping
- 요청 URL을 어떤 메서드가 처리할지 mapping해주는 애노테이션이다.

컨트롤러나 컨트롤러의 메서드에 적용한다.
@RequestMapping("/list"), @RequestMapping("/home, /about");
@RequestMapping("/admin", method=RequestMethod.GET)

@GetMapping
- @RequestMapping(Method=RequestMethod.GET)과 같음
@PostMapping, @PutMapping, @PatchMapping, @DeleteMapping은 유추 가능함.

@RequestAttribute
- Request에 설정되어 있는 속성 값을 가져올 수 있다.

@RequestBody
- 요청이 온 데이터(JSON이나 XML형식)를 바로 클래스나 model로 매핑하기 위한 애노테이션

@RequestHeader
- Request의 header값을 가져올 수 있다. 메소드의 파라미터에 사용
@RequestHeader(value="Accept-Language")String acceptLanguage 로 사용 //ko-KR,ko;q=0.8,en-US;q=0.6

@RequestParam
- @PathVariable과 비슷하다. request의 parameter에서 가져오는 것이다. 메소드의 파라미터에 사용됨

@RequestPart
- Request로 온 MultipartFile을 바인딩해준다.
@RequestPart("file")MultipartFile file로 받아올 수 있음.

@ResponseBody
- view가 아닌 JSON 형식의 값을 응답할 때 사용하는 애노테이션으로 문자열을 리턴하면 그 값을 http response header가 아닌 response body에 들어간다.
만약 객체를 return하는 경우 JACKSON 라이브러리에 의해 문자열로 변환되어 전송된다.
context에 설정된 resolver를 무시한다고 보면된다. (viewResolver)

@PathVariable
- 메서드 파라미터 앞에 사용하면서 해당 URL에서 {특정값}을 변수로 받아 올 수 있다.

@ExceptionHandler(ExceptionClassName.class)
- 해당 클래스의 예외를 캐치하여 처리한다.

@ControllerAdvice
- 클래스 위에 ControllerAdvice를 붙이고 어떤 예외를 잡아낼 것인지는 각 메소드 상단에 @ExceptionHandler(에외클래스명.class)를 붙여서 기술한다.

@RestControllerAdvice
- 문법적 설탕으로 @ControllerAdvice + @ResponseBody다.

@ResponseStatus
- 사용자에게 원하는 response code와 reason을 리턴해주는 애노테이션
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "my page URL changed..") => 예외처리 함수 앞에 사용한다.

@EnableEurekaServer
- Eureka 서버로 만들어준다.

@EnableDiscoveryClient
- Eureka 서버에서 관리될 수 있는 클라이언트 임을 알려주기위한 애노테이션

@Transactional
- 데이터베이스 트랜잭션을 설정하고 싶은 메서드에 애노테이션을 적용하면 메서드 내부에서 일어나는 데이터베이스 로직이 전부 성공하게되거나 데이터베이스 접근중 하나라도 실패하면 다시 롤백할 수 있게 해주는 애노테이션
@Transaction(readOnly=true, rollbackFor=Exception.class) : readOnly는 읽기전용임을 알리고 rollbackFor는 해당 Exception이 생기면 롤백하라는 뜻
@Transaction(noRollbackFor=Exception.class)는 해당 Exception이 나타나도 롤백하지 말라는 뜻
@Transaction(timeout = 10)은 10초안에 해당 로직을 수행하지 못하면 롤백하라는 뜻.

########################################
# Bean 등록 Annotation
########################################
@Component
컴포넌트를 나타내는 일반적인 스테리오 타입으로  태그와 동일한 역할을 함
@Controller, @Service , @Repository를 다 포함하고 있다.

@Repository
퍼시스턴스 레이어, 영속성을 가지는 속성(파일, 데이터베이스)을 가진 클래스

@Service
서비스 레이어, 비지니스 로직을 가진 클래스

@Controller
프리젠테이션 레이어, 웹 어플리케이션에서 웹 요청과 응답을 처리하는 클래스

-> @Repository, @Service, @Controller는 더 특정한 유즈케이스에 대한 @Component의 구체화된 형태

########################################
# Bean 의존관계 주입 Annotation
########################################
@Autowired, @Resource annotation은 의존하는 객체를 자동으로 주입해주는 annotation이다

@Autowired
정밀한 의존관계 주입이 필요한 경우에 유용.
@Autowired는 프로퍼티, setter 메서드, 생성자, 일반 메서드에 적용 가능.
의존하는 객체를 주입할 때 주로 Type을 이용
@Autowired는 ,  태그와 동일한 역할.

@Resource
어플리케이션에서 필요로 하는 자원을 자동 연결할 때 사용
@Resource는 poperty, setter 메서드에 적용 가능
의존하는 객체를 주입할 때 주로 Name을 이용

@Value
단순한 값을 주입할 때 사용되는 annotation.
@Value("Spring")은 와 동일한 역할

@Qualifier
@Qualifier는 @Autowired annotation과 같이 사용.
@Autowired는 타입으로 찾아서 주입하므로, 동일 타입의 Bean 객체가 여러 개 존재할 때 특정 Bean을 찾기 위해 사용

########################################
# 참고 사이트
########################################
https://zeroturnaround.com/rebellabs/spring-framework-annotations-cheat-sheet/
https://zetawiki.com/wiki/%EC%8A%A4%ED%94%84%EB%A7%81_%EC%95%A0%EB%84%88%ED%85%8C%EC%9D%B4%EC%85%98
http://blog.naver.com/PostView.nhn?blogId=wwwkang8&logNo=220994093310
https://jeong-pro.tistory.com/151
https://cornswrold.tistory.com/8
https://gmlwjd9405.github.io/2018/12/02/spring-annotation-types.html
https://smallgiant.tistory.com/11
https://s262701-id.tistory.com/91
https://lalwr.blogspot.com/2018/04/spring-annotation.html
https://blog.hanumoka.net/2018/07/20/spring-20180720-Spring-MVC-Annotation/

https://kdyang.tistory.com/54

' Spring Framework' 카테고리의 다른 글

Spring Bean이란?  (0) 2019.03.27
롬복(lombok)이란?  (0) 2019.03.27