Tech/Spring & Jpa

애너테이션과 스프링 애너테이션

mozzi329 2023. 1. 18. 23:25
728x90

📌 알림


해당 글은 공부 목적으로 작성한 글입니다.

 

📌 애너테이션(Annotation)


애너테이션(Annotation)
주석처럼 프로그램에 영향을 미치지 않으면서, 유용한 정보를 제공하며, 프로그램에게 추가적인 정보를 제공하는 메타데이터이다.

동작
애너테이션을 정의하고, 애너테이션을 원하는 위치에 배치하면, 코드가 실행되는 중에 Reflection을 이용하여 추가 정보를 획득하여 기능을 수행한다.

Reflection
구체적인 클래스 타입을 알지 못해도 그 클래스의 메서드, 타입, 변수들에 접근할 수 있도록 해주는 자바 API이다. 런타임에 지금 실행되고 있는 클래스를 가져와서 실행해야하는 경우, 동적으로 객체를 생성하고 메서드를 호출한다.

Annotation 자체는 아무런 동작을 가지지 않는 단순한 표식일 뿐이지만, Reflection을 이용하면 Annotation의 적용 여부와 엘리먼트 값을 읽고 처리할 수 있다.

Spring 컨테이너(BeanFactory)에서 객체가 호출되면 객체의 인스턴스를 생성하게 되는데 이 때 필요하게 된다. 즉, 프레임워크에서 유연성있는 동작을 위해 쓰인다.

Reflection을 이용하면 Annotation 지정만으로도 원하는 클래스를 주입할 수 있다.

 

📌 리플렉션(Reflection)의 사용

class Person {
    int age;

    Person() {
        this.age = 27;
    }

    Person(int age) {
        this.age = age;
    }

    int getAge() {
        return this.age;
    }
}

✔️ 생성자 찾기

Class clazz = Class.forName("Person");
Constructor constructor = clazz.getDeclaredConstructor();

✔️ 메서드 찾기

Class clazz = Person.class;
Method[] methods = clazz.getDeclaredMethods();    
System.out.println(methods[0].invoke(clazz.newInstance()))

✔️ 필드 변경

Class clazz = Person.class;
Field[] field = clazz.getDeclaredFields();
System.out.println(field[0]);

✔️ 필드 가져오기

Class clazz = Person.class;
Field[] field = clazz.getDeclaredFields();

Person person = new Person();
field[0].set(person, 17);
System.out.println(field[0].get(person));

 

📌 스프링 애너테이션(Spring Annotation)


@ComponentScan

Component, Service, Repository, Controller, Configuration 애너테이션이 붙은 클래스 빈들을 찾아서 Context에 빈을 등록해주는 애너테이션
⋇ 전부 다 Component 애너테이션을 사용하지는 않는다.
Repository 애너테이션 등으로 분리해서 사용하는 이유는, 예를 들어 @Repository는 DAO에서 발생할 수 있는 unchecked exception들을 스프링의 DataAccessException으로 처리할 수 있기 때문이다. 또한 가독성에서도 해당 애노테이션을 갖는 클래스가 무엇을 하는지 단 번에 알 수 있다.


@EnableAutoConfiguration
Application Context를 만들 때 자동으로 빈 설정을 해주는 기능을 수행하는 애너테이션
spring.factories 내부에 여러 Configuration들이 있고 조건에 따라 Bean이 등록되게 되는데 메인 클래스를 실행하면 @EnableAutoConfiguration에 의해 spring.factories 안에 있는 수많은 자동 설정들이 조건에 따라 적용되어 수 많은 Bean들이 생성된다.


@Component
개발자가 직접 작성한 class를 Bean으로 등록하기 위한 애너테이션

@Bean
개발자가 직접 제어가 불가능한 외부 라이브러리 등을 빈으로 만들려할 때 사용되는 애너테이션

@Configuration
@Configuration을 클래스에 적용하고 @Bean을 해당 class의 메서드에 적용하면 @autowired로 Bean을 부를 수 있다.

@Autowired
스프링이 Type에 따라 알아서 Bean을 주입해주는 애너테이션

Type을 먼저 확인한 후 못 찾으면 Name에 따라 주입한다. 강제로 주입하고자 하는 경우 @Qulifier을 같이 명시해야 한다.

@Qualifier
@Autowired와 같이 쓰이며, 같은 타입의 빈 객체가 있을 때 원하는 빈이 주입될 수 있도록 하는 애너테이션
같은 타입의 빈이 두 개 이상 존재하는 경우 스프링이 어떤 빈을 주입해야할 지 알 수 없어서 스프링 컨테이너를 초기화하는 과정에서 예외가 발생한다. @Qualifier는 @Autowired와 함께 사용하여 정확히 어떤 bean을 사용할지 지정하여 특정 의존 객체를 주입할 수 있다.


@Resource
이름으로 빈 객체를 연결해주는 애너테이션

@Autowired와 마찬가지로 Bean 객체를 주입해주는데 차이점은 Autowired는 타입으로, Resource는 이름으로 연결해준다. 애노테이션 사용으로 인해 특정 Framework에 종속적인 애플리케이션을 구성하지 않기 위해서 @Resource 사용을 권장한다.
@ControllerAPI와 view를 동시에 사용하는 경우에 사용보통 view 화면 return을 목적으로 사용한다. @RestControllerview가 필요 없이 API만 지원하는 서비스에서 사용한다.

@SpringBootApplication
@Configuration, @EnableAutoConfiguration, @ComponentScan 3가지를 하나로 합친 애노테이션

 

📌 모의 면접


애너테이션에 대해 설명해주세요.
애너테이션은 주석처럼 프로그램에 영향을 미치지 않으면서, 프로그램에게 추가적인 정보를 제공하는 메타데이터입니다.
애너테이션을 정의하고, 애너테이션을 원하는 위치에 배치하면, 코드가 실행되는 중에 리플렉션을 이용하여 추가 정보를 획득하여 기능을 수행합니다.

리플렉션은 구체적인 클래스 타입을 알지 못해도 그 클래스의 메서드, 타입, 변수들에 접근할 수 있도록 해주는 자바 API로, 런타임에 지금 실행되고 있는 클래스를 가져와서 실행해야하는 경우, 동적으로 객체를 생성하고 메서드를 호출하는 등, 프레임워크에서 유연성있는 동작을 위해 사용됩니다.

스프링 애너테이션에 대해 설명해주세요. (+⍺)
스프림 프레임워크에서 지원하는 애너테이션으로 대표적으로,
특정 애너테이션을 스캔하는 ComponentScan 애너테이션,
개발자가 직접 작성한 클래스를 등록해주는 Component 애너테이션,
외부 라이브러리 객체를 등록해주는 Bean 애너테이션,
Type에 따라 빈 객체를 자동으로 주입해주는 Autowired 애너테이션,
Bean 애너테이션으로 등록된 메서드를 가지는 클래스에 작성하면 자동으로 빈 객체를 Autowired해주는 Configuration 애너테이션이 있습니다.