Spring Annotation

bearMin·2024년 8월 5일

들어가면서

Spring Boot 관련 글을 찾아보다보면 @Controller 와 같은 것들을 자주 볼 수 있다. 근데 저런 것들이 한두개가 있는 것이 아니다.. 특히 코드를 작성하다보면 저 @를 쓰지 않아서 문제가 되는 경우들도 존재하는데 저게 대체 무엇이길래 사용을 하는지 알아보는 시간을 가져보자!


Annotation이란?

사전상으로는 주석이라는 의미이지만 Java에서는 주석 이상의 기능을 가지고 있다. Annotation은 Java 코드에 추가하여 사용할 수 있는 메타데이터의 일종으로 단순 주석의 기능이 아니라 특별한 기능을 사용할 수 있다.

⇒ 우리가 읽는 주석이 아닌 컴파일러가 읽는 주석이라고 생각하면 편하다!


Annotation은 프로그램 코드의 일부가 아닌 프로그램에 관한 데이터를 제공하고 코드에 정보를 추가하는 정형화된 방법으로 Annotation을 사용할 경우 코드가 깔끔해지고 재사용이 가능해진다.

Annotation을 사용하기 위한 순서는 다음과 같다.

  1. Annotation 정의

  2. Class에 Annotation을 배치

  3. 코드가 실행되는 도중에 Reflection을 이용하여 추가 정보를 획득 & 기능을 실시

    💡 Reflection?
    구체적인 Class의 Type을 알지 못하더라도 해당 Class의 method, type, variable에 
    접근할 수 있도록 해주는 자바 API 
    컴파일된 바이트 코드를 통해 Runtime에 동적으로 특정 Class의 정보를 추출할 수 있는 프로그래밍 기법

Spring Boot Web Annotation?

Spring Boot Web이란?

Spring Boot를 사용할 때 웹 애플리케이션을 빠르고 쉽게 구축할 수 있도록 도와주는 도구이다.

내장된 웹 서버를 제공하여 웹 애플리케이션을 실행하고 관리하는데 필요한 모든 설정을 자동으로 처리하며 간단한 설정으로 HTTP 엔드포인트를 생성하고 관리할 수 있다.

또한 Spring MVC와 같은 웹 프레임워크와 통합되어 효율적인 웹 애플리케이션 개발을 지원한다.


Spring Boot Web을 사용하기 위해선 다음과 같은 의존성을 추가해주어야한다.

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
}

@SpringBootApplication 이란?

Spring Boot를 자동으로 실행시켜주는 Annotation으로 Bean 등록은 두 단계로 진행된다.

  • @ComponentScan을 통해 Component들을 Bean으로 등록한다.
  • @EnableAutoConfiguration을 통해 미리 정의해둔 자바 설정 파일들을 Bean으로 등록한다.
    💡 Bean이란?
    스프링 IoC 컨테이너에 의해 인스턴스화되어 조립되거나 관리되는 객체

@ComponentScan 이란?

@Component(@Service, @Repository, @Controller), @Configuration이 붙은 Bean들을 찾아서 Context에 Bean을 등록해 주는 Annotation이다.

이때 @Component로 다 쓰지 않고 @Repository, @Service, @Controller등 구분을 해서 사용하는 이유는 코드를 더 명확하게 구조화하고 역할을 분리하여 유지보수성을 향상시킬 수 있기 때문이다.


=> 즉, 비즈니스 로직과 데이터베이스 조작이 분리되어 코드의 재사용성과 테스트 용이성을 높일 수 있다!


@EnableAutoConfiguration 이란?

프로젝트의 외부 라이브러리들의 Bean들을 등록하는 Annotation이다. 이때 외부 라이브러리들의 Bean들을 등록하기 위한 대상은 @Configuration 로 정의되거나 @Conditional 로 시작하는 클래스를 대상으로 한다.

💡 자동설정(Auto-Configuration)이란?
프로젝트에 추가한 jar 파일의 의존성들을 기반으로 프로젝트의 스프링 애플리케이션을 
자동적으로 설정하기 위해 수행되는 과정

@Configuration 이란?

Spring Bean 설정을 위한 클래스임을 나타내는 Annotation이다.
이 Annotation이 지정된 클래스는 하나 이상의 @Bean 메소드를 포함할 수 있다. 이때, @Bean을 해당 클래스의 메소드에 적용하면 @Autowired로 Bean을 부를 수 있다.


@Bean 이란?

Spring Container에 의해 관리되는 Bean 객체를 정의하는 메소드임을 나타내는 Annotation이다. @Configuration 어노테이션이 지정된 클래스 내에서 사용된다.


<@Configuration
public class ApplicationConfig {
	  @Bean
    public ArrayList<String> arraylist() {
    	return new ArrayList<String>();
    }
}

ArrayList같은 라이브러리 등을 Bean으로 등록하기 위해서는 별도로 해당 라이브러리 객체를 반환하는 메소드를 만들고 @Bean을 사용하면 된다.

위의 경우 @Bean에 아무런 값을 지정하지 않았으므로 메소드 이름을 camelCase로 변경한 것이 Bean id로 등록된다.

메소드가 arraylist()인 경우 arrayList가 Bean id가 된다.


<@Configuration
public class ApplicationConfig {
	  @Bean(name="myarray")
    public ArrayList<String> array() {
    	return new ArrayList<String>();
    }
}

@Bean에 name이라는 값을 이용하면 원하는 id로 Bean을 등록할 수 있다.


@Component 란?

Spring 관리 Bean으로 등록되는 클래스임을 나타내는 Annotation이다. 일반적으로 의존성 주입(Dependency Injection)을 위해 사용된다.

@ComponentScan 선언에 의해 특정 패키지 안의 클래스들을 자동 스캔하여 @Component 어노테이션이 있는 클래스들에 대하여 Bean 인스턴스를 생성한다.


<@Component
public class Example {
	public Example() {
    	System.out.println("Hello World!");
    }
}

@Component(value="myexample")
public class Example {
	public Example() {
    	System.out.println("Hello World!");
    }
}

Component에 대한 추가 정보가 없다면 Class의 이름을 camelCase로 변경한 것이 Bean id로 사용된다.

하지만 @Bean과 다르게 @Component는 name이 아닌 value를 이용해 Bean의 이름을 지정한다.


@Autowired 란?

필드, setter 메소드, 생성자에 사용하며 Type에 따라 알아서 Bean을 주입해주는 역할을 한다.
@Autowired을 사용하면 스프링이 자동적으로 값을 할당한다.


Bean을 주입받는 방식은 3가지가 있다.

// 1. 필드 주입
public class MyService {
		@Autowired
		private MyRepository myRepository;
}

// 2. Setter 주입
public class MyService {
		private MyRepository myRepository;
		
		public void setMyRepository(MyRepository myRepository) {
				this.myRepository = myRepository;
		}
}

// 3. 생성자 주입
public class MyService {
		private final MyRepository myRepository;
		
		private MyService(MyRepository myRepository) {
				this.myRepository = myRepository;
		}
}

Spring에서는 생성자 주입을 권장한다.

그 이유는 필드 주입을 할 경우에는 필드와 너무 강하게 결합이 되어있어서, 즉 의존도가 높아서 테스트할 때 어려움이 있다.

Setter 주입을 할 경우에는 런타임에 Reflection을 통해 누군가 변경을 할 수 있는 위험이 있다.

그러나 생성자 주입의 경우 생성 시점에 주입이 되기 때문에 변경이 불가능하며 final 키워드를 추가함으로써 컴파일에 까먹지 않고 주입이 가능하다.


@Controller 란?

Spring MVC 애플리케이션에서 컨트롤러로 사용되는 클래스임을 나타내는 Annotation이다.


@RestController 란?

Spring에서 Controller 중 View로 응답하지 않는 Controller를 의미하며, 메소드의 반환 결과를 JSON 형태로 반환한다.

@RestController가 적혀있는 Controller의 메소드는 HttpResponse로 바로 응답이 가능하다. @ResponseBody 역할을 자동적으로 해주는 Annotation이다.


@Controller와 @RestController의 차이점은 무엇일까?

  • @Controller API와 view를 동시에 사용하는 경우에 사용한다. 대신 API 서비스로 사용하는 경우는 @ResponseBody를 사용하여 객체를 반환한다. view return이 주목적이다.
  • @RestController view가 필요없는 API만 지원하는 서비스에서 사용한다. @RequestMapping 메서드가 기본적으로 @ResponseBody 의미를 가정한다. data return이 주목적이다.

즉,  @RestController  =  @Controller  +  @ResponseBody


@Service 란?

Service Class에서 쓰이는 Annotation으로, 비즈니스 로직을 수행하는 클래스라는 것을 나타내는 용도이다.


@Repository 란?

Repository Class에서 쓰이는 Annotation으로, DB에 접근하는 메소드를 가지고 있는 클래스에서 사용이 된다.


@Value 란?

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

@Value("${spring.redis.host}")
private String host;

@CrossOrigin 란?

CORS 보안상의 문제로 브라우저에서 리소스를 현재 origin에서 다른 곳으로의 AJAX요청을 방지하기 위해 사용한다.

💡 CORS와 AJAX?

CORS는 Cross-Origin Resource Sharing의 약자로 다른 출처이기 때문에 발생하는 에러이다.

AJAX는 Asynchronous Javascript And Xml(비동기식 자바스크립트와 xml)의 약자로 
JavaScript를 이용해 서버와 브라우저가 비동기 방식으로 데이터를 교환할 수 있는 통신 기능이다.

요청과 응답 관련 Annotation?

@RequestMapping 란?

어떤 URL을 어떤 메소드가 처리할지 매핑해주는 Annotation이다. 보통 메소드가 처리해야할 엔드포인트 URL와 HTTP 메서드를 정의하는데 사용을 하며, Controller 또는 Controller의 메소드에 적용한다.

<@RequestMapping("/")
public class MyController {

    public void example() {
		// 로직 구현
    }
    
}

@GetMapping 이란?

HTTP GET 요청을 특정 메서드에 매핑하는 데 사용이 된다.

이 Annotation은 @RequestMapping의 축약형이며, 주로 조회 작업에 사용된다.


@PostMapping 이란?

HTTP POST 요청을 특정 메서드에 매핑하는 데 사용이 된다.

이 Annotation은 @RequestMapping의 축약형이며, 주로 생성 작업에 사용된다.


@PutMapping 이란?

HTTP PUT 요청을 특정 메서드에 매핑하는 데 사용이 된다.

이 Annotation은 @RequestMapping의 축약형이며, 주로 업데이트(수정) 작업에 사용된다.

이때 해당 수정 작업은 전체 리소스를 변경하는데 주로 사용이 된다.


@PatchMapping 이란?

HTTP PATCH 요청을 특정 메서드에 매핑하는 데 사용이 된다.

이 Annotation은 @RequestMapping의 축약형이며, 주로 업데이트(수정) 작업에 사용된다.

이때 해당 수정 작업은 일부 리소스를 변경하는데 주로 사용이 된다.


@DeleteMapping 이란?

HTTP DELETE 요청을 특정 메서드에 매핑하는 데 사용이 된다.

이 Annotation은 @RequestMapping의 축약형이며, 주로 삭제 작업에 사용된다.


@RequestParam 이란?

URL에서 파라미터 값과 이름을 함께 전달하게 하는 Annotation으로 주로 HTTP GET 요청에서 많이 사용한다.

// ~/user?userId=1

@GetMapping("/user")
public User getUser(@RequestParam("userId") int userId) {
		// 로직 구현
}

@RequestBody 이란?

요청이 온 데이터를 바로 Class나 model로 매핑하기 위한 Annotation이다.

예를 들어, JSON 이나 XML같은 데이터를 적절한 messageConverter로 읽을 때 사용하거나 POJO 형태의 데이터 전체로 받는 경우에 사용한다.


@PathVariable 이란?

URL에서 {특정값}을 변수로 받아올 수 있다. URI에서 각 구분자에 들어오는 값을 처리해야 할 때 사용하며, REST API에서 값을 호출할 때 주로 많이 사용한다.

// ~/user/1

@GetMapping("/user/{userId}")
public User getUser(@PathVariable("userId") int userId) {
		// 로직 구현
}

@ResponseBody 이란?

HTTP 응답 본문(Body)을 직접 데이터로 반환하고자 할 때 사용한다. 즉, view가 아닌 JSON 형식의 값을 응답할 때 사용하는 Annotation으로, 문자열을 리턴하면 그 값이 http response header가 아닌 response body에 들어간다.

이미 @RestController 어노테이션이 붙어 있다면, 쓸 필요가 없다. 그러나 단순 컨트롤러라면, HttpResponse로 응답 할 수 있게 해준다.


Lombok Annotation?

Lombok이란?

Java의 라이브러리로 반복되는 메소드를 Annotation을 사용해 자동으로 작성해주는 편리한 라이브러리이다.


@NoArgsConstructor 이란?

Class의 기본생성자를 자동으로 생성해주는 Annotation이다.


@AllArgsConstructor 이란?

모든 필드 값을 파라미터로 받는 생성자를 자동으로 생성해주는 Annotation이다.


@RequiredArgsConstructor 이란?

final이나 @NonNull인 필드 값만 파라미터로 받는 생성자를 추가한다.


@Getter 란?

Class 내 모든 필드의 Getter 메소드를 자동 생성해주는 Annotation이다.


@Setter 란?

Class 내 모든 필드의 Setter 메소드를 자동 생성해주는 Annotation이다.


@ToString 이란?

Class 내 모든 필드의 toString 메소드를 자동 생성해주는 Annotation이다.


@Builder 란?

어느 필드에 어떤 값을 채워야 할지 명확하게 정하여 객체 생성 시점에 값을 채워주는 Annotation이다.

생성 시점에 값을 채워는 것은 생성자와 동일하지만 Builder를 사용하면 어느 필드에 어떤 값을 넣어야 할지 명확하게 인지할 수 있다.

@Builder
public class Memer {
		@Id
		private String uderId;
		private String userName;
}

//객체 생성
Member member = Member.builder()
					.userId(parameter.getUserId())
					.userName(parameter.getUserName())
					.build();

@Data 란?

@Getter,  @Setter,  @EqualsAndHashCode,  @AllArgsConstructor을 포함한 Lombok에서 제공하는 필드와 관련된 모든 코드를 생성하는 Annotation이다.


JPA Annotaion?

JPA란 Java 진영에서 ORM(Object-Relational Mapping) 기술 표준으로 사용하는 인터페이스 모음으로 Java 애플리케이션에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스이다.

💡 ORM이란?
Java Class와 RDB의 Table을 매핑하는 것

@Entity 란?

실제 DB Table과 매핑될 Class임을 나타내는 Annotation이다.

DB의 Table과 일대일로 매칭이 되는 객체의 단위이며, Entity 객체의 인스턴스 하나가 Table에서 하나의 레코드 값을 의미한다.


@Id 란?

해당 Table의 기본키(Primary Key : PK) 필드를 의미한다.


@GeneratedValue 이란?

기본키의 값을 자동으로 생성해준다.

기본값은 AUTO로 MySQL의 auto_increment와 같이 자동으로 증가하는 정수형 값이 된다. 이때 가능한 Entity의 PK는 Java Long 타입의 Auto_increment를 주로 사용한다.


@Column 이란?

Table의 컬럼을 나타내며 선언하지 않더라도 Entity Class의 필드는 모두 컬럼이 된다.

@Column을 생략하면 필드명을 사용해서 컬럼명과 매핑한다.

이 Annotation은 기본값 외에 추가로 변경이 필요한 옵션이 있을 경우 사용한다.

<@Entity
public class Blog {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;

	@Column(nullable = false)
	private String title;

	@Column(nullable = false)
	private String content;
}

정리하자면

Annotation은 주석이라는 의미를 가지지만 Java에서는 주석 이상의 특별한 의미나 기능을 부여하는 방법을 뜻한다!

가장 기초적인 Annotation들이며, 수많은 Annotation들이 있으니 많이 찾아보고 공부를 해야한다!

profile
소소한 공부기록

0개의 댓글