[Spring]Annotation
in SPRING
Annotation ์ด๋?
Annotation(@)
์ ์ฌ์ ์ ์๋ฏธ๋ก๋ ์ฃผ์์ด๋ผ๋ ๋ป์ด๋ค. ์๋ฐ์์ Annotation
์ ์ฝ๋ ์ฌ์ด์ ์ฃผ์์ฒ๋ผ ์ฐ์ด๋ฉฐ ํน๋ณํ ์๋ฏธ, ๊ธฐ๋ฅ์ ์ํํ๋๋ก ํ๋ ๊ธฐ์ ์ด๋ค. ์ฆ, ํ๋ก๊ทธ๋จ์๊ฒ ์ถ๊ฐ์ ์ธ ์ ๋ณด๋ฅผ ์ ๊ณตํด์ฃผ๋ ๋ฉํ๋ฐ์ดํฐ๋ผ๊ณ ๋ณผ ์ ์๋ค. meta data
: ๋ฐ์ดํฐ๋ฅผ ์ํ ๋ฐ์ดํฐ)
๋ค์์ ์ด๋ ธํ ์ด์ ์ ์ฉ๋๋ฅผ ๋ํ๋ธ ๊ฒ์ด๋ค.
์ปดํ์ผ๋ฌ์๊ฒ ์ฝ๋ ์์ฑ ๋ฌธ๋ฒ ์๋ฌ๋ฅผ ์ฒดํฌํ๋๋ก ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ค.
์ํํธ์จ์ด ๊ฐ๋ฐ ํด์ด ๋น๋๋ ๋ฐฐ์น์ ์ฝ๋๋ฅผ ์๋์ผ๋ก ์์ฑํ ์ ์๋๋ก ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ค.
์คํ์(๋ฐํ์์)ํน์ ๊ธฐ๋ฅ์ ์คํํ๋๋ก ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํ๋ ์์๋ ๋ค์๊ณผ ๊ฐ๋ค.
- ์ด๋ ธํ ์ด์ ์ ์ ์ํ๋ค.
- ํด๋์ค์ ์ด๋ ธํ ์ด์ ์ ๋ฐฐ์นํ๋ค.
- ์ฝ๋๊ฐ ์คํ๋๋ ์ค์ Reflection์ ์ด์ฉํ์ฌ ์ถ๊ฐ ์ ๋ณด๋ฅผ ํ๋ํ์ฌ ๊ธฐ๋ฅ์ ์ค์ํ๋ค.
Reflection ์ด๋?
Reflection
์ด๋ ํ๋ก๊ทธ๋จ์ด ์คํ ์ค์ ์์ ์ ๊ตฌ์กฐ์ ๋์์ ๊ฒ์ฌํ๊ณ , ์กฐ์ฌํ๊ณ , ์์ ํ๋ ๊ฒ์ด๋ค.
Reflection
์ ํ๋ก๊ทธ๋๋จธ๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋ณด์ฌ์ฃผ๊ณ , ๋ค๋ฅธ ํฌ๋งท์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๊ณ , ํต์ ์ ์ํด serialization(์ง๋ ฌํ)๋ฅผ ์ํํ๊ณ , bundling์ ํ๊ธฐ ์ํด ์ผ๋ฐ ์ํํธ์จ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ง๋ค๋๋ก ๋์์ค๋ค.
Java์ ๊ฐ์ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์์ Reflection
์ ์ฌ์ฉํ๋ฉด ์ปดํ์ผ ํ์์ ์ธํฐํ์ด์ค, ํ๋, ๋ฉ์๋์ ์ด๋ฆ์ ์์ง ๋ชปํด๋ ์คํ ์ค์ ํด๋์ค, ์ธํฐํ์ด์ค, ํ๋ ๋ฐ ๋ฉ์๋์ ์ ๊ทผํ ์ ์๋ค.
๋ํ ์๋ก์ด ๊ฐ์ฒด์ ์ธ์คํด์คํ ๋ฐ ๋ฉ์๋ ํธ์ถ์ ํ์ฉํ๋ค.
Java์ ๊ฐ์ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์์ Reflection
์ ์ฌ์ฉํ์ฌ ๋ฉค๋ฒ ์ ๊ทผ ๊ฐ๋ฅ์ฑ ๊ท์น์ ๋ฌด์ํ ์ ์๋ค.
[EX] reflection์ ์ฌ์ฉํ๋ฉด ์๋ ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํด๋์ค์์ private ํ๋์ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์๋ค.
Spring์์ BeanFactory๋ผ๋ Container์์ ๊ฐ์ฒด๊ฐ ํธ์ถ๋๋ฉด ๊ฐ์ฒด์ ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ฒ ๋๋๋ฐ ์ด ๋ ํ์ํ๊ฒ ๋๋ค. ์ฆ, ํ๋ ์์ํฌ์์ ์ ์ฐ์ฑ์๋ ๋์์ ์ํด ์ฐ์ธ๋ค.
Annotation
์์ฒด๋ ์๋ฌด๋ฐ ๋์์ ๊ฐ์ง์ง ์๋ ๋จ์ํ ํ์์ผ ๋ฟ์ด์ง๋ง, Reflection
์ ์ด์ฉํ๋ฉด Annotation
์ ์ ์ฉ ์ฌ๋ถ์ ์๋ฆฌ๋จผํธ ๊ฐ์ ์ฝ๊ณ ์ฒ๋ฆฌํ ์ ์๋ค.
Class์ ์ ์ฉ๋ Annotation
์ ๋ณด๋ฅผ ์ฝ์ผ๋ ค๋ฉด java.lang.Class๋ฅผ ์ด์ฉํ๊ณ ํ๋, ์์ฑ์, ๋ฉ์๋์ ์ ์ฉ๋ ์ด๋
ธํ
์ด์
์ ๋ณด๋ฅผ ์ฝ์ผ๋ ค๋ฉด Class์ ๋ฉ์๋๋ฅผ ํตํด java.lang.reflect ํจํค์ง์ ๋ฐฐ์ด์ ์ป์ด์ผ ํ๋ค.
Class.forName(), getName(), getModifier(), getFields() getPackage()๋ฑ๋ฑ ์ฌ๋ฌ ๋ฉ์๋๋ก ์ ๋ณด๋ฅผ ์ป์ ์ ์๋ค.
Reflection
์ ์ด์ฉํ๋ฉด Annotation
์ง์ ๋ง์ผ๋ก๋ ์ํ๋ ํด๋์ค๋ฅผ ์ฃผ์
ํ ์ ์๋ค.
// Without reflection
Foo foo = new Foo();
foo.hello();
// With reflection
Object foo = Class.forName("complete.classpath.and.Foo").newInstance();
// Alternatively: Object foo = Foo.class.newInstance();
Method m = foo.getClass().getDeclaredMethod("hello", **new** Class<?>[0]);
m.invoke(foo);
@RestController
@Controller
์@ResponseBody
๋ฅผ ํฉ์น ์ด๋ ธํ ์ด์ ์ผ๋ก ๋ฉ์๋์ ๋ฐํ ๊ฒฐ๊ณผ๋ฅผ JSON ํํ๋ก ๋ฐํํด์ค๋๋ค.
@RequestMapping
- ์์ฒญ URL์ ์ด๋ค ๋ฉ์๋๊ฐ ์ฒ๋ฆฌํ ๊ฒ์ธ์ง ๋งคํํด์ฃผ๋ ์ด๋ ธํ ์ด์ ์ ๋๋ค.
- Controller๋ Controller์ method์ ์ ์ฉํ๋ค.
- ์์ฒญ์ ๋ฐ๋ ํ์์ธ GET, POST, PATCH, PUT, DELETE ๋ฅผ ์ ์ํ๊ธฐ๋ ํ๋ค. (์ง์ ์ํ ์ GET)
@Bean
์คํ๋ง ์ปจํ ์ด๋์ Bean์ ๋ฑ๋กํ๋๋ก ํด์ฃผ๋ ์ด๋ ธํ ์ด์ ์ ๋๋ค.
@Bean
- ๊ฐ๋ฐ์๊ฐ ์ง์ ์ ์ด ๋ถ๊ฐ๋ฅํ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ Bean์ผ๋ก ๋ฑ๋กํ๊ธฐ ์ํด ์ฌ์ฉ๋ฉ๋๋ค.
@Component
- ๊ฐ๋ฐ์๊ฐ ์ง์ ์์ฑํ ํด๋์ค๋ฅผ Bean์ผ๋ก ๋ฑ๋กํ๊ธฐ ์ํด ์ฌ์ฉ๋ฉ๋๋ค.
@Autowired
- ์์ฑ์๋ setter ๋ฉ์๋ ์์ด ์์กด์ฑ์ ์ฃผ์ ํด์ ์๋์ผ๋ก ๊ฐ์ฒด๋ฅผ ์์ฑํด์ฃผ๋ ์ด๋ ธํ ์ด์ ์ ๋๋ค.
@Configuration
- ํด๋น ํด๋์ค๊ฐ ํ๊ฒฝ ์ค์ ๊ณผ ๊ด๋ จ๋ ํ์ผ์ด๋ผ๋ ๊ฒ์ ์๋ ค์ฃผ๋ ์ด๋ ธํ ์ด์ ์ ๋๋ค.
- ํด๋น ํด๋์ค์ ์ ์๋
@Bean
์ด ์ ์ฉ๋ ๋ฉ์๋๋@Autowired
๋ฅผ ํตํด์ ๋ถ๋ฅผ ์ ์์ต๋๋ค.
@ConfigurationProperties
- ํ๋กํผํฐ ํ์ผ์ ์ฝ์ด์์ ํด๋น ๊ฐ๋ค์ ์ฌ์ฉํ ์ ์๊ฒ ๋ง๋ค์ด์ค๋๋ค.
@Transactional
- ํด๋น ํด๋์ค ๋๋ ๋ฉ์๋์ ํธ๋์ญ์ ์ ์ ์ฉ์์ผ ์ค๋๋ค.
- DB์ ์ก์ธ์คํ๋ ์ฌ๋ฌ ์ฐ์ฐ๋ค์ ํ๋์ ํธ๋์ญ์ ์ผ๋ก ์ฒ๋ฆฌํ์ฌ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ์๋์ผ๋ก ๋กค๋ฐฑ ์์ผ ์ค๋๋ค.
@Controller
- Presentation Layer
- ์์ฒญ๊ณผ ์๋ต์ ์ฒ๋ฆฌํด์ฃผ๋ ํด๋์ค์ ์ฌ์ฉ๋ฉ๋๋ค.
@Service
- Service Layer
- ๋น์ฆ๋์ค ๋ก์ง์ ๋ด๋นํ๋ ํด๋์ค์ ์ฌ์ฉ๋ฉ๋๋ค.
@Repository
- Persistence Layer
- DB์ ์ก์ธ์คํ๋ ํด๋์ค์ ์ฌ์ฉ๋ฉ๋๋ค. (DB์ ๊ทผํ๋ Method๋ฅผ ๊ฐ์ง๊ณ ์๋ class์์ ์ฌ์ฉ(DAO))
@ExceptionHandler
- ์ปจํธ๋กค๋ฌ ๋จ์์ ๋ฐ์ํ๋ ์์ธ๋ฅผ ์ก์์ ์ฒ๋ฆฌํด์ฃผ๋ ๋ฉ์๋์ ์ฌ์ฉ๋ฉ๋๋ค.
@ControllerAdvice
- ์ ์ญ์์ ๋ฐ์ํ๋ ์์ธ๋ค์ ์ก์์ ์ฒ๋ฆฌํด์ฃผ๋ ํด๋์ค์ ์ฌ์ฉ๋ฉ๋๋ค.
@ComponentScan
- @Component์ @Service, @Repository, @Controller, @Configuration์ด ๋ถ์ ํด๋์ค Bean๋ค์ ์ฐพ์์ Context์ bean๋ฑ๋ก์ ํด์ฃผ๋ Annotation์ด๋ค.
@Component Annotation์ด ์๋ ํด๋์ค์ ๋ํ์ฌ bean ์ธ์คํด์ค๋ฅผ ์์ฑ
ApplicationContext.xml์
<bean id="jeongpro" class="jeongpro" />
๊ณผ ๊ฐ์ด xml์ bean์ ์ง์ ๋ฑ๋กํ๋ ๋ฐฉ๋ฒ๋ ์๊ณ ์์ ๊ฐ์ดAnnotation
์ ๋ถ์ฌ์ ํ๋ ๋ฐฉ๋ฒ๋ ์๋ค.base-package๋ฅผ ๋ฃ์ผ๋ฉด ํด๋น ํจํค์ง ์๋์ ์๋ ์ปดํฌ๋ํธ๋ค์ ์ฐพ๊ณ ๊ทธ ๊ณผ์ ์ spring-context-๋ฒ์ (4.3.11.RELEASE).jar์์ ์ฒ๋ฆฌํ๋ค.
Spring์์ @Component๋ก ๋ค ์ฐ์ง ์๊ณ @Repository, @Service, @Controller๋ฑ์ ์ฌ์ฉํ๋ ์ด์ ๋, ์๋ฅผ๋ค์ด @Repository๋ DAO์ ๋ฉ์๋์์ ๋ฐ์ํ ์ ์๋ unchecked exception๋ค์ ์คํ๋ง์ DataAccessException์ผ๋ก ์ฒ๋ฆฌํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
๋ํ ๊ฐ๋ ์ฑ์์๋ ํด๋น ์ ๋ ธํ ์ด์ ์ ๊ฐ๋ ํด๋์ค๊ฐ ๋ฌด์์ ํ๋์ง ๋จ ๋ฒ์ ์ ์ ์๋ค.
- ์๋์ผ๋ก ๋ฑ๋ก๋๋ Bean์ ์ด๋ฆ์ ํด๋์ค์ ์ฒซ๋ฌธ์๊ฐ ์๋ฌธ์๋ก ๋ฐ๋ ์ด๋ฆ์ด ์๋์ ์ฉ๋๋ค. HomeController -> homeController
@Controller ์ @RestController ์ ์ฐจ์ด
- @Controller API์ view๋ฅผ ๋์์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์ ์ฌ์ฉํ๋ค. ๋์ API ์๋น์ค๋ก ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๋ @ResponseBody๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค. view(ํ๋ฉด) return์ด ์ฃผ๋ชฉ์ ์ด๋ค.
- @RestController view๊ฐ ํ์์๋ API๋ง ์ง์ํ๋ ์๋น์ค์์ ์ฌ์ฉํ๋ค. Spring 4.0.1๋ถํฐ ์ ๊ณต @RequestMapping ๋ฉ์๋๊ฐ ๊ธฐ๋ณธ์ ์ผ๋ก @ResponseBody ์๋ฏธ๋ฅผ ๊ฐ์ ํ๋ค. data(json, xml ๋ฑ) return์ด ์ฃผ๋ชฉ์ ์ด๋ค.
์ฆ, @RestController = @Controller + @ResponseBody ์ด๋ค.
@ModelAttribute
view์์ ์ ๋ฌํด์ฃผ๋ parameter๋ฅผ Class(VO/DTO)์ ๋ฉค๋ฒ ๋ณ์๋ก binding ํด์ฃผ๋ Annotation์ด๋ค.
binding ๊ธฐ์ค์
<input name="id" />
์ฒ๋ผ ์ด๋ค ํ๊ทธ์ name๊ฐ์ด ํด๋น Class์ ๋ฉค๋ฒ ๋ณ์๋ช ๊ณผ ์ผ์นํด์ผํ๊ณ set method๋ช ๋ ์ผ์นํด์ผํ๋ค.
class Person{
String id;
public void setId(String id){ this.id = id;}
public String getId(){ return this.id }
}
@Controller
@RequestMapping("/person/*")
public class PersonController{
@RequestMapping(value = "/info", method=RequestMethod.GET)
//view์์ myMEM์ผ๋ก ๋์ ธ์ค ๋ฐ์ดํฐ์ ๋ด๊ธด id ๋ณ์๋ฅผ Personํ์
์ person์ด๋ผ๋ ๊ฐ์ฒด๋ช
์ผ๋ก ๋ฐ์ธ๋ฉ.
public void show(@ModelAttribute("myMEM") Person person, Model model)
{ model.addAttribute(service.read(person.getId())); }
}
@RequestBody
์์ฒญ์ด ์จ ๋ฐ์ดํฐ(JSON์ด๋ XMLํ์)๋ฅผ ๋ฐ๋ก Class๋ model๋ก ๋งคํํ๊ธฐ ์ํ Annotation์ด๋ค.
POST๋ PUT, PATCH๋ก ์์ฒญ์ ๋ฐ์๋์, ์์ฒญ์์ ๋์ด์จ body ๊ฐ๋ค์ ์๋ฐ ํ์ ์ผ๋ก ํ์ฑํด์ค๋ค.
HTTP POST ์์ฒญ์ ๋ํด request body์ ์๋ request message์์ ๊ฐ์ ์ป์ด์ ๋งคํํ๋ค. RequestData๋ฅผ ๋ฐ๋ก Model์ด๋ ํด๋์ค๋ก ๋งคํํ๋ค.
์ด๋ฅผํ ๋ฉด JSON ์ด๋ XML๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ ํ messageConverter๋ก ์ฝ์ ๋ ์ฌ์ฉํ๊ฑฐ๋ POJO ํํ์ ๋ฐ์ดํฐ ์ ์ฒด๋ก ๋ฐ๋ ๊ฒฝ์ฐ์ ์ฌ์ฉํ๋ค.
@ResponseBody
- HttpMessageConverter๋ฅผ ์ด์ฉํ์ฌ JSON ํน์ xml ๋ก ์์ฒญ์ ์๋ตํ ์ ์๊ฒ ํด์ฃผ๋ Annotation์ด๋ค.
view๊ฐ ์๋ JSON ํ์์ ๊ฐ์ ์๋ตํ ๋ ์ฌ์ฉํ๋ Annotation์ผ๋ก ๋ฌธ์์ด์ ๋ฆฌํดํ๋ฉด ๊ทธ ๊ฐ์ http response header๊ฐ ์๋ response body์ ๋ค์ด๊ฐ๋ค.
์ด๋ฏธ RestController Annotation์ด ๋ถ์ด ์๋ค๋ฉด, ์ธ ํ์๊ฐ ์๋ค. ํ๋ ๊ทธ๋ ์ง ์์ ๋จ์ ์ปจํธ๋กค๋ฌ๋ผ๋ฉด, HttpResponse๋ก ์๋ต ํ ์ ์๊ฒ ํด์ค๋ค.
๋ง์ฝ ๊ฐ์ฒด๋ฅผ returnํ๋ ๊ฒฝ์ฐ JACKSON ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ํด ๋ฌธ์์ด๋ก ๋ณํ๋์ด ์ ์ก๋๋ค.
- context์ ์ค์ ๋ viewResolver๋ฅผ ๋ฌด์ํ๋ค๊ณ ๋ณด๋ฉด๋๋ค.
[์ฐธ๊ณ ]
https://velog.io/@gillog/Spring-Annotation-%EC%A0%95%EB%A6%AC