Spring Annotation 정리
Annotation 이란 ?
- Anootation은 사전적 의미로 주석이라는 뜻이다. 자바에서 Annotation은 코드 사이에 주석처럼 쓰이며 특별한 의미, 기능을 수행하도록 제공하는 기술이다. 즉, 프로그램에게 추가적인 정보를 제공해주는 메타데이터 라고 볼 수 있다.
- Annotation의 사용순서는 다음과 같다.
- 어노테이션을 정의한다.
- 클래스에 어노테이션을 배치한다.
- 코드실행 중 Reflection을 이용하여 추가 정보를 획득하여 기능을 실행한다.
Reflection 이란?
Reflection이란 프로그램 실행 중 자신의 구조와 동작을 검사,조사, 수정하는 것이다.
Reflection은 프로그래머가 데이터를 보여주고, 다른 포맷의 데이터를 처리,통신하기 위해 serialization(직렬화)를 수행하고, bundling하기 위해 일반 소프트웨어 라이브러리를 만들도록 도와준다.
Java와 같은 객체 지향 프로그래밍 언어에서 Reflection을 사용하면 컴파일 타임에 인터페이스, 필드, 메소드의 이름을 몰라도 실행 중 접근할 수 있다.
Java와 같은 객체 지향 프로그래밍 언어에서 Reflection을 사용해 멤버 접근 가능성 규칙을 무시할 수 있다. ex) reflection을 사용하면 서드 파티 라이브러리의 클래스에서 private 필드의 값을 변경할 수 있다.
Spring에서 BeanFactory라는 Container에서 객체가 호출되면 객체의 인스턴스를 생성하게 되고 이 때 필요하게 된다. 즉, 프레임워크에서 유연성있는 동작을 위해 사용된다.
Reflection을 이용하면 Annotation의 적용 여부와 엘리먼트 값을 읽고 처리할 수 있다.
다음 메소드를 통해 정보를 얻을 수 있다.
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);
Annotation 종류
Component
@Component은 개발자가 직접 작성한 Class를 Bean으로 등록하기 위한 Annotation이다.
@Component public class Student{ public Student() { System.out.println("hi"); } } @Component(value="mystudent") public class Student{ public Student() { System.out.println("hi"); } }
Component에 대한 추가 정보가 없으면 class의 이름을 camelCase로 변경한 것이 Bean ID로 사용된다.
하지만 @Bean 과 다르게 @Component 는 name 이 아닌 value를 이용해 Bean의 이름을 지정한다.
Autowired
@Autowired는 type에 따라 알아서 Bean을 주입한다. 한 객체에 대하여 의존성을 주입할 때 사용된다.
스프링이 자동적으로 값을 할당하며 DAO나 Service에 관한 객체들을 주입 시킬 때 많이 사용한다.
만약 필드, 생성자, 입력 파라미터가 여러개인 메소드일 경우 @Qualifier를 활용해 적용할 수 있다.
만약 Autowired를 interface class에 사용했고 그 interface class를 상속받은 class가 여러개일 경우에는 에러가 발생하기 때문에 다음과같이 @Qualifier를 같이 명시해줘야한다.
@Component("tv9") public class ssTV09 implements iTV { @Autowired //단일로 사용될 경우 여러개의 스피커가 존재하기 때문에 오류 발생. @Qualifier("enc") // encSpeaker를 사용하기위해 명시. private iSpeaker05 speaker; public ssTV09(iSpeaker05 speaker) { ... } }
Controller
Spring의 Controller를 의미한다. Spring MVC에서 Controller class에 쓰인다.
@Controller Annotation을 붙이면 핸들러가 스캔할 수 있는 Bean객체가 되 서블릿용 컨테이너에 생성된다. 마찬가지로 @Repository, @Service Annotation은 해당 class를 루트 컨테이너에 Bean객체로 생성해주는 Annotation이다.
컨트롤러 : @Controller (프레젠테이션 레이어, 웹 요청과 응답을 처리)
로직 처리 : @Service (서비스 레이어, 내부에서 자바 로직을 처리)
외부I/O 처리 : @Repository (퍼시스턴스 레이어, DB나 파일같은 외부 I/O 작업을 처리)
참고로 객체 내에서 데이터 변경 작업이 있는 VO(DTO) 객체와 같은 경우 동기화 문제로 인해 Bean객체로 사용하지 않는다. Bean 객체는 항상 데이터 변경이 없는 객체에 한해 사용하는 점에 유의해야 한다.
연관지어 @WebServlet과 @Controller 의 차이에 대해 알아보자.
WebServlet과 Spring MVC Controller는 같은 일을 하는데 사용된다.
WebServlet은 서블릿을 선언할 때 사용되는 Annotation이며 이 Annotation이 사용된 클래스는 Servlet Container에 의해 처리된다. 사용시 속성 값을 통해 해당 Servlet과 매핑될 URL패턴을 지정한다.
@Target(value=TYPE) @Retention(value=RUNTIME) @Documented public @interface WebServlet
Controller는 @Component의 구체화된 역할을 한다. classpath scanning을 통해 구현 클래스를 자동으로 감지할 수 있도록 해준다. 일반적으로 RequestMapping Annotation을 기반으로 한 handler method와 함께 사용한다.
@Target(value=TYPE) @Retention(value=RUNTIME) @Documented @Component public @interface Controller
Repository, Service
@Repository는 간단하게 데이터베이스에 접근하는 method를 가진 class에 사용된다.
@Repository("userDAO") public class UserDAO { ... }
다음과같이 DAO클래스를 명시해주면 루트 컨테이너에 Bean 객체로 생성되고 이 "userDAO"는 new를 이용해 생성하는게 아닌 컨테이너에서 받아와야 한다. 루트컨테이너는 어디서든 공유가능하기 때문에, 다음과같은 의존성 주입(DI)(@Resource, @Inject, @Autowired) Annotation을 이용해 객체를 받아올 수 있다.
Annotation들은 같은 Bean 객체에서만 작동하기 때문에 Bean으로 만들지 않은 일반 클래스에서는 사용해봤자 아무 소용 없다. 하지만 일부 DTO객체 등 데이터 변경 작업을 동반하는 클래스 외, 로직을 가진 클래스들은 대부분 @Service Annotation을 통해 Bean객체로 등록해주기 때문에 크게 문제되진 않는다.
즉 @Repository는 DB접근과 관련된 코드가 모여있는 곳이고, @Service는 패키지를 확인하고 DB접근 외에 비즈니스 로직관련 코드가 모여있는 곳이라 생각하면 된다.
Reference
- https://www.inflearn.com/questions/77417 (Repository, Service 차이)
- https://codevang.tistory.com/258 (Repositroy, Service Annotation)
- https://gmlwjd9405.github.io/2018/12/22/webservlet-vs-controller.html (@WebServlet,@Controller Servlet Annotation)
- https://velog.io/@gillog/Spring-Annotation-정리 (Spring Annotation 정리)
'Spring, Spring Boot' 카테고리의 다른 글
Spring Web Layer (0) | 2023.01.12 |
---|---|
Spring MVC 동작과정 (0) | 2023.01.11 |
SOLID 객체지향 설계의 5가지 원칙 (0) | 2022.05.13 |
Spring AOP 정리 (0) | 2022.01.01 |