33 분 소요

자주 사용하는 어노테이션들 정리 (계속 업데이트됩니다.)

@Aspect

스프링 AOP(Aspect-Oriented Programming)에서 Aspect를 정의할 때 사용되는 어노테이션이다.

Aspect는 애플리케이션의 여러 부분에서 공통적으로 발생하는 관심사를 모듈화하고 캡슐화하기 위해 사용된다.

Aspect 클래스

@Aspect 어노테이션을 붙인 클래스는 Aspect 클래스로 지정된다.

이 클래스는 관심사(Aspect)를 정의하고 어떤 시점에 어떤 작업을 수행할지를 결정한다.

Advice 메서드

Aspect 클래스 내부에는 하나 이상의 Advice 메서드가 있어야 한다.

Advice 메서드는 언제, 어떤 작업을 수행할지를 정의한다.

스프링 AOP에서 일반적으로 사용되는 Advice 종류에는 Before, After, Around, AfterReturning, AfterThrowing 등이 있다.

Pointcut 표현식

@Aspect 어노테이션을 사용한 클래스는 Pointcut 표현식을 정의할 수 있다.

Pointcut은 어떤 메서드가 Aspect에 의해 처리되어야 하는지를 결정하는데 사용된다.

Pointcut은 Advice 메서드와 결합하여 어떤 메서드에서 어떤 작업을 수행할지를 결정한다.

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class LoggingAspect {

    @Before("execution(* com.example.service.*.*(..))")
    public void logBeforeServiceMethod() {
        System.out.println("Logging before service method execution.");
    }
}

이 코드에서 LoggingAspect 클래스는 @Aspect 어노테이션을 가지고 있으며, logBeforeServiceMethod 메서드는 @Before 어노테이션을 사용하여 특정 패키지의 모든 서비스 메서드가 실행되기 전에 로깅 작업을 수행한다.

즉, @Aspect 어노테이션을 사용하여 Aspect 클래스를 정의하고,

그 안에서 Advice 메서드와 Pointcut 표현식을 사용하여 언제 어떤 작업을 수행할지를 설정한다.

이렇게 설정된 Aspect는 스프링 AOP에 의해 관리되고, 애플리케이션에서 관심사를 쉽게 모듈화할 수 있게 도와준다.

@Autowired

의존성 주입을 자동으로 처리하기 위해 사용되는 어노테이션이다.

이 어노테이션을 사용하면 스프링 컨테이너가 해당 타입의 빈(bean)을 찾아서 필드, 생성자, 메서드 등을 통해 해당 빈을 주입한다.

@Autowired 어노테이션은 스프링 프레임워크에서 의존성 주입을 간편하게 처리할 수 있도록 도와주는 중요한 어노테이션 중 하나이다.

이를 통해 코드의 가독성을 높이고 의존성 주입을 쉽게 관리할 수 있다.

의존성 주입

@Autowired 어노테이션은 스프링 빈들 간의 의존성을 주입하는 데 사용된다.

예를 들어, 서비스 클래스에서 리포지토리 클래스나 다른 서비스 클래스와 같은 의존성을 주입할 때 유용하다.

@Service
public class ProductService {
    private final ProductRepository productRepository;

    @Autowired
    public ProductService(ProductRepository productRepository) {
        this.productRepository = productRepository;
    }
    
    // ...
}

// ProductService 클래스의 생성자에 @Autowired 어노테이션이 적용되어 ProductRepository 빈이 자동으로 주입된다.

자동 빈 탐색

@Autowired를 사용하면 스프링 컨테이너는 해당 타입의 빈을 자동으로 찾아 의존성을 주입한다.

빈의 이름 또는 타입을 기반으로 자동으로 빈을 찾는다.

생성자, 메서드, 필드에 적용

@Autowired 어노테이션은 생성자, 메서드, 필드에 적용할 수 있다.

생성자 주입은 일반적으로 권장되는 방법이며, 필드나 메서드 주입도 사용 가능하다.

@Service
public class ProductService {
    private final ProductRepository productRepository;

    @Autowired
    public ProductService(ProductRepository productRepository) {
        this.productRepository = productRepository;
    }
    
    // ...
}

옵션 처리

@Autowired로 주입되는 빈이 없을 경우 예외가 발생한다.

이를 방지하기 위해 @Autowired 어노테이션을 사용한 필드나 메서드에 @Nullable 어노테이션을 추가하거나, Java 8 이상에서는 Optional을 사용하여 옵션 처리를 할 수 있다.

@Autowired(required = false)
private SomeBean someBean;

// @Autowired(required = false)로 설정하면 someBean이 없어도 예외가 발생하지 않는다.

일반적으로 생성자가 하나일 경우에는 @Autowired 어노테이션을 붙이지 않아도 Spring이 알아서 DI를 적용한다.

하지만, 생성자가 하나 이상일 경우, DI를 적용하기 위한 생성자에 반드시 @Autowired 어노테이션을 붙여야 한다.

@AllArgsConstructor

클래스의 모든 필드를 파라미터로 받는 생성자를 자동으로 생성해주는 기능을 제공한다.

이 어노테이션을 사용하면 모든 필드를 초기화 하는 생성자를 간단하게 추가할 수 있다.

주로 데이터 객체, 엔티티 클래스에서 많이 사용된다.

import lombok.AllArgsConstructor;

@AllArgsConstructor
public class Person {
    private String name;
    private int age;
}

위의 코드에서는 Person 클래스에 모든 필드를 초기화하는 생성자를 직접 작성하지 않았지만,

@AllArgsConstructor 어노테이션을 사용하여 컴파일 시에 다음과 같은 생성자가 자동으로 생성된다.

public Person(String name, int age) {
    this.name = name;
    this.age = age;
}

따라서 이 클래스를 사용할 때는 아래와 같이 모든 필드를 인자로 하는 생성자를 호출할 수 잇다.

Person person = new Person("Alice", 30);

@Async

Spring Framework에서 비동기 메서드 실행을 표시하는 데 사용되는 어노테이션이다.

이 어노테이션을 사용하면 메서드가 별도의 스레드에서 비동기적으로 실행되며,

호출자는 해당 메서드가 완료될 때까지 블로킹되지 않는다.

주로 웹 애플리케이션에서 긴 대기 시간이 필요한 작업을 백그라운드에서 수행하거나

병렬 처리를 위한 경우에 유용하다.

@EnableAsync 어노테이션 추가

Spring Application 클래스에 @EnableAsync 어노테이션을 추가하여 Spring의 비동기 처리를 활성화한다.

@SpringBootApplication
@EnableAsync
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

@Async 어노테이션을 메서드에 추가

비동기로 실행하려는 메서드에 @Async 어노테이션을 추가한다.

@Service
public class MyService {
    @Async
    public void asyncMethod() {
        // 비동기 작업 수행
    }
}

이제 asyncMethod가 비동기로 실행되며, 호출자는 이 메서드가 완료될 때까지 기다리지 않는다.

아래는 @Async 어노테이션을 사용할 때 주의할 점이다.

  • @EnableAsync 를 사용하여 비동기 기능을 활성화해야 한다.
  • 비동기 메서드는 void 또는 Future 반환 유형을 가질 수 있다.
  • Spring의 비동기 처리는 기본적으로 내부 스레드 풀을 사용하며, 스레드 풀의 크기 및 기타 설정은 구성 파일에서 조정할 수 있다.

@Bean

스프링 컨테이너에게 해당 메서드가 스프링 빈을 생성하고 관리하는 메서드임을 알려주는 역할을 한다.

@Bean 어노테이션이 적용된 메서드는 스프링 컨테이너에 의해 호출되어 해당 빈 객체를 생성하고,

이후에는 스프링 애플리케이션 컨텍스트 내에서 이 빈을 사용할 수 있다.

빈 정의 메서드

@Bean 어노테이션을 적용한 메서드는 스프링 빈의 정의를 담고 있다.

이 메서드가 호출되면 해당 빈의 인스턴스를 생성하고 초기화할 수 있다.

명시적 구성

@Bean 어노테이션은 주로 @Configuration 어노테이션이 적용된 클래스 내에 작성된다.

이를 통해 스프링 애플리케이션 컨텍스트에 수동으로 빈을 등록하거나, 외부 라이브러리나 설정 클래스를 빈으로 등록할 수 있다.

속성 설정

@Bean 어노테이션을 사용한 메서드 내에서 빈의 속성을 설정하거나 다른 빈들과의 의존성을 주입할 수 있다.

빈(Bean)이란?

스프링 프레임워크에서 관리되는 객체를 가리킨다.

스프링은 이러한 빈들을 생성, 관리, 검색, 재사용하고, 빈들 간의 의존성을 해결하여 애플리케이션의 개발과 유지보수를 더욱 편리하게 만들어준다.

스프링 빈은 Java 클래스로 정의되며, @Component, @Service, @Repository, @Controller 와 같은 어노테이션으로 빈을 표시하거나 XML 설정 파일을 통해 등록할 수 있다.

또한 빈들간의 의존성은 @Autowired, @Qualifier, @Resource 등의 어노테이션을 사용하여 설정할 수 있다.

스프링 빈을 사용하면 객체의 생명주기 관리, 의존성 주입, 트랜잭션 관리 등을 스프링 프레임워크가 대신 처리해주므로 개발자는 핵심 비즈니스 로직에 집중할 수 있게 된다.

스프링 컨테이너에 등록

빈은 스프링 컨테이너에 등록되어야 한다.

스프링 컨테이너는 이 빈들을 관리하고, 필요한 시점에 인스턴스를 생성하거나 반환한다.

생성과 소멸 관리

스프링은 빈의 생명주기를 관리한다.

빈이 생성되는 시점, 초기화 메서드 호출, 소멸되는 시점을 관리한다.

의존성 주입

빈들 간의 의존성을 주입할 수 있다.

이는 객체 간의 결합도를 낮추고 유연한 애플리케이션을 만들 수 있도록 도와준다.

AOP와 같은 기능 제공

스프링은 빈들에 대한 AOP지원을 제공하여 횡단 관심사를 분리하고 중복 코드를 제거할 수 있게 한다.

스코프 관리

빈은 다양한 스코프에서 관리될 수 있으며, 스코프에 따라 빈의 생명주기와 범위가 다르게 설정될 수 있다.

주요 스코프로는 Singleton, Prototype, Request, Session 등이 있다.

빈(Bean) 사용 여부

빈을 사용하는 것은 스프링 애플리케이션을 개발하는데 매우 편리하고 강력한 도구이다.

그러나 모든 곳에 빈을 사용하는 것이 항상 최선인 것은 아니다.

서비스 클래스

비즈니스 로직을 구현한 서비스 클래스는 빈으로 등록하여 스프링 컨테이너에의해 관리된다.

이러한 서비스 클래스는 주로 비즈니스 로직을 처리하고 다른 빈과 협력한다.

데이터 액세스 객체 (DAO)

DB나 다른 저장소와 상호 작용하는 DAO 클래스는 빈으로 등록하여 데이터 액세스 로직을 수행한다.

서비스 관리

서비스 관리, 로깅, 인증, 보안 등과 관련된 공통 기능을 제공하는 빈을 만들어 사용한다.

이러한 빈들은 애플리케이션 전반에 걸쳐 공유되거나 필요한 곳에서 주입되어 사용된다.

의존성 주입

빈을 사용하여 의존성 주입을 수행한다.

스프링 빈을 생성하고, 필요한 의존성을 주입하여 객체 간의 결합도를 낮추고 테스트 용이성을 높인다.

테스트

스프링은 테스트에서도 빈을 사용하여 테스트용 빈을 등록하고 테스트를 수행하는 데 도움을 준다.

빈(Bean) 사용 예시

웹 애플리케이션 컨트롤러

@Controller
public class MyController {
    @Autowired
    private MyService service;

    @GetMapping("/hello")
    public String sayHello() {
        return service.getGreeting();
    }
}

서비스 클래스

@Service
public class MyService {
    public String getGreeting() {
        return "Hello, World!";
    }
}

데이터 액세스 객체 (DAO)

@Repository
public class MyRepository {
    public String fetchData() {
        // 데이터베이스에서 데이터를 조회하고 반환
    }
}

서비스 간 의존성 주입

@Service
public class OrderService {
    @Autowired
    private PaymentService paymentService;

    public void placeOrder(Order order) {
        // 주문 로직 수행
        paymentService.processPayment(order.getTotalAmount());
    }
}

AOP

@Aspect
@Component
public class LoggingAspect {
    @Before("execution(* com.example.service.*.*(..))")
    public void logBeforeMethodCall(JoinPoint joinPoint) {
        // 메서드 호출 전에 로깅
    }
}

@Builder

빌더 패턴(Builder Pattern)을 자동으로 생성해주는 역할을 한다.

빌더 패턴은 객체 생성을 더 편리하게 만들어주는 디자인 패턴 중 하나이며,

많은 매개변수를 갖는 생성자를 가독성 있게 작성할 수 있게 도와준다.

가독성 향상

객체를 생성할 때 많은 매개변수를 가진 생성자를 사용하면 어떤 값이 어떤 필드에 대응되는지 파악하기 어렵다.

@Builder를 사용하면 메서드 체이닝을 통해 각 필드의 값을 명시적으로 설정할 수 있어 가독성이 향상된다.

필요한 필드만 설정

필요한 필드만 설정하고, 나머지는 기본값을 사용할 수 있다.

이를 통해 생성하려는 객체의 일부 필드만 설정하는 데 유용하다.

불변성(Immutability) 유지

생성된 객체는 변경 불가능하도록 만들 수 있으며,

이는 다중 스레드 환경에서 안전하게 사용할 수 있도록 도와준다.

메서드 체이닝

빌더 패턴을 사용하면 한 줄에 여러 필드를 설정할 수 있으므로 코드가 간결해 진다.

@Getter
@Builder
public class Person {
    private String firstName;
    private String lastName;
    private int age;
}

// 사용
Person person = Person.builder()
    .firstName("John")
    .lastName("Doe")
    .age(30)
    .build();

@Configuration

스프링 컨테이너에게 해당 클래스가 구성(Configuration) 클래스임을 알려주는 역할을 한다.

스프링 컨테이너는 이 어노테이션이 적용된 클래스를 스캔하고, 그 안에 정의된 빈(bean)을 생성하고 관리한다.

빈 설정 클래스로 표시

@Configuration 어노테이션이 적용된 클래스는 스프링 애플리케이션 컨텍스트를 설정하기 위한 클래스로 인식된다.

이 클래스 안에서 스프링 빈들을 정의하고 구성할 수 있다.

빈 정의 메서드

@Bean 어노테이션과 함께 메서드를 정의하여 해당 메서드가 스프링 빈의 인스턴스를 생성하도록 할 수 있다.

이 메서드들은 보통 @Configuration 어노테이션이 적용된 클래스 내에 작성된다.

빈 스캐닝

@ComponentScan 어노테이션과 함께 사용하여 패키지를 기반으로 빈을 자동으로 스캔하고 등록할 수 있다.

환경 설정 관리

@PropertySource, @Value 어노테이션과 함께 사용하여 프로퍼티 파일을 읽고 환경 설정을 관리할 수 있다.

@ComponentScan

스프링 애플리케이션에서 컴포넌트를 검색하고 빈으로 등록하기 위해 사용된다.

이 어노테이션은 스프링 컨텍스트 내에서 빈으로 등록할 클래스들을 찾을 위치를 지정한다.

패키지 스캔

@ComponentScan은 주로 특정 패키지나 패키지들을 대상으로 컴포넌트 검색을 수행한다.

이 패키지와 하위 패키지에서 스프링 컴포넌트를 검색한다.

BasePackages 속성

basePackages 속성을 사용하여 컴포넌트 스캔이 시작될 패키지를 지정할 수 있다.

예를 들어 @ComponentScan(basePackages = “com.example”)는 “com.example”패키지에서 컴포넌트를 검색한다.

basePackageClasses 속성

클래스를 기반으로 스캔을 수행하려면 basePackageClasses 속성을 사용할 수 있다.

이 속성은 특정 클래스를 기준으로 패키지를 계산하고 해당 패키지에서 컴포넌트를 검색한다.

includeFilters와 excludeFilters

includeFilters 및 excludeFilters 속성을 사용하여 어떤 클래스를 스캔할 것인지 또는 제외할 것인지를 지정할 수 있다.

UseDefaultFilters 속성

useDefaultFilters 속성은 기본 필터를 사용할지 여부를 지정하는데, 기본적으로 true로 설정되어 있어 기본 필터를 사용한다.

false로 설정하면 커스텀 필터만 사용한다.

@Controller

스프링 프레임워크에서 웹 애플리케이션의 컨트롤러 클래스를 정의할 때 사용되는 어노테이션이다.

이 어노테이션을 사용하면 해당 클래스가 웹 요청을 처리하는 컨트롤러 역할을 하게 된다.

요청 처리

@Controller 어노테이션이 적용된 클래스는 웹 요청을 처리하고, 요청에 대한 응답을 생성하는 역할을 한다.

Spring MVC와 통합

@Controller는 스프링 MVC (Model-View-Controller) 아키텍처와 함께 사용되며,

웹 애플리케이션의 사용자 인터페이스를 구축하는 데 주로 활용된다.

HTTP 요청 처리

@Controller 어노테이션이 적용된 메서드는 특정 URL 패턴에 대한 HTTP 요청을 처리하고,

해당 요청에 따른 비즈니스 로직을 수행한다.

뷰와 모델 연결

@Controller는 비즈니스 로직을 수행한 결과를 모델에 저장하고,

이 모델을 템플릿 엔진을 통해 뷰로 전달하여 사용자에게 보여준다.

요청 매핑

@RequestMapping 어노테이션을 메서드에 사용하여 어떤 URL 패턴에 대한 요청을 처리할지 지정할 수 있다.

스프링 컨테이너 관리

@Controller 어노테이션이 적용된 클래스는 스프링 컨테이너에 등록되어 빈으로 관리되며,

DI (의존성 주입) 등 스프링의 기능을 활용할 수 있다.

@Controller
public class MyController {

    @RequestMapping("/hello")
    public String sayHello() {
        return "hello"; // "hello"는 뷰 이름을 나타내며, 해당 뷰를 렌더링한다.
    }
}

위의 코드에서 @Controller 어노테이션이 적용된 MyController 클래스는 “/hello” URL에 대한 요청을 처리하고 “hello”라는 뷰를 반환한다.

@Constraint

자바에서 Bean Validation(또는 JSR 380) 기반으로 한 데이터 유효성 검증을 사용할 때 사용되는 메타 어노테이션 중 하나이다.

이 어노테이션은 사용자 정의(커스텀) 검증 어노테이션을 만들 때 사용되며, 해당 어노테이션이 유효성 검사를 어떻게 수행해야 하는지를 지정한다.

validatedBy

유효성 검사를 실제로 수행하는 검증기(Validator) 클래스를 지정한다.

이 클래스는 ConstraintValidator 인터페이스를 구현해야 한다.

message

검증 실패 시 사용자에게 보여질 에러 메시지를 지정한다.

이 메시지는 다국어 지원 및 다양한 메시지 리소스에서 가져올 수 있도록 유연하게 지정할 수 있다.

groups (선택 사항)

검증을 그룹별로 나누어 수행할 때 어떤 그룹에 해당 검증을 적용할지를 지정한다.

기본값은 빈 배열로, 모든 그룹에서 검증을 수행한다.

사용자 정의 검증 어노테이션을 만들 때, @Constraint 어노테이션을 사용하여 해당 어노테이션을 위의 구성 요소와 함께 정의하고, 검증 로직을 실제로 구현하는 검증기 클래스를 작성한다.

예를 들어, 사용자 정의 검증 어노테이션인 @ValidEmail을 만들고 이를 통해 이메일 주소의 유효성을 검사하는 경우 다음과 같이 정의할 수 있다.

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EmailValidator.class)
public @interface ValidEmail {
    String message() default "Invalid email address";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

여기서 EmailValidator 클래스는 ConstraintValidator 인터페이스를 구현하여 실제 이메일 주소 유효성 검사를 수행한다.

@Column

엔티티 클래스의 필드와 데이터베이스 테이블의 열(column) 간의 매핑을 지정하는 데 사용된다.

주로 관계형 데이터베이스와 자바 객체 간의 데이터 매핑을 정의하는 JPA에서 활용된다.

필드명과 열명의 매핑

엔티티 클래스의 필드와 데이터베이스 테이블의 열을 매핑할 수 있다.

엔티티 클래스의 필드명과 데이터베이스 테이블의 열명이 다를 때 사용된다.

데이터 타입 및 길이 설정

해당 필드의 데이터 타입, 길이, 저일도 등을 설정할 수 있다.

NULL 값 허용 여부 설정

nullable 속성을 사용하여 해당 열이 Null 값을 허용하는지 여부를 설정할 수 있다.

고유 제약 조건 설정

unique 속성을 사용하여 해당 열의 값이 고유(unique)해야 함을 나타낼 수 있다.

기타 설정 옵션

@Column 어노테이션을 통해 다양한 데이터베이스 관련 설정을 지정할 수 있다.

@Entity
@Table(name = "employees")
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "full_name", length = 100, nullable = false)
    private String fullName;

    @Column(name = "job_title")
    private String title;

    @Column(name = "salary")
    private BigDecimal salary;

    // getters and setters
}

@Column 어노테이션을 사용하여 fullName, title, salary 필드와 데이터 베이스 열 간의 매핑을 지정하고,

열의 이름, 길이, Null 허용 여부 등을 설정한다.

이렇게 JPA를 사용하여 엔티티와 데이터베이스 간의 매핑을 세밀하게 제어할 수 있다.

@Data

자바 클래스의 Getter, Setter, equals(), hashCode(), toString() 등의 메서드를 자동으로 생성해주는 기능을 제공한다.

@Data 어노테이션을 사용하기 위해 프로젝트의 빌드 도구에 Lombok 라이브러리를 추가해야 한다.

그러면 컴파일 시점에 Lombok이 자동으로 코드를 생성해준다.

import lombok.Data;

@Data
public class Person {
    private String name;
    private int age;
}

// 생성된 메서드를 사용할 때
public class Main {
    public static void main(String[] args) {
        Person person = new Person();
        person.setName("John");
        person.setAge(30);

        System.out.println(person.getName()); // Getter 메서드 사용
        System.out.println(person); // toString() 메서드 사용
    }
}

@EnableAutoConfiguration

스프링 부트 애플리케이션에서 자동 구성(자동 설정)을 활성화하는데 사용된다.

이 어노테이션을 통해 클래스 패스와 설정에 따라 필요한 빈을 자동으로 설정한다.

자동 설정

스프링 부트는 클래스 패스의 종속성, 프로퍼티 설정 및 사용자 정의 설정에 기반하여 애플리케이션을 자동으로 구성한다.

스프링 부트 스타터

스프링 부트 스타터 종속성은 일반적인 라이브러리 모음을 제공하며,

이러한 스타터를 사용하면 @EnableAutoConfiguration 어노테이션을 통해 필요한 자동 설정을 활성화할 수 있다.

예를 들어, spring-boot-starter-web 스타터는 웹 애플리케이션을 위한 필수적인 설정을 활성화한다.

자동 구성 비활성화

특정 자동 구성을 비활성화하려면 exclude 속성을 사용하여 해당 클래스를 지정하면 된다.

예를 들어 @EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})를 사용하면 데이터 소스 자동 구성을 비활성화할 수 있다.

사용자 정의 자동 설정

사용자 정의 자동 설정 클래스를 작성하려면 @Configuration 어노테이션을 추가하고, 클래스를 META-INF/spring.factories 파일에 등록한다.

그러면 사용자 정의 자동 설정이 자동으로 활성화된다.

@Entity

자바 표준 ORM(Object-Relational Mapping) 기술인 JPA(Java Persistence API)에서 사용되는 어노테이션 중 하나이다.

이 어노테이션은 엔티티 클래스를 나타내는 데 사용되며, 해당 클래스가 데이터베이스의 테이블과 매핑되는 것을 나타낸다.

엔티티 매핑 [더보기] <- 여기서 더 자세한 내용을 볼 수 있다.

객체-관계 매핑

엔티티 클래스를 데이터베이스 테이블과 매핑하기 위해 사용됩니다. 엔티티 클래스의 필드와 데이터베이스 테이블의 열 간의 매핑을 설정하고 관리할 수 있도록 합니다.

데이터베이스 연산

JPA를 사용하여 엔티티 객체를 데이터베이스에 저장, 검색, 수정 및 삭제하는 등의 데이터베이스 연산을 수행할 때 @Entity 어노테이션이 부여된 클래스를 대상으로 합니다.

@Entity
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private double price;

    // Getter와 Setter 메서드, 기타 필드 및 메서드들
}

Product 클래스는 @Entity 어노테이션을 통해 JPA에 의해 관리되는 엔티티임을 나타낸다.

또한 @Id 어노테이션과 @GeneratedValue 어노테이션을 사용하여 id 필드를 기본 키로 설정하고 자동으로 생성되도록 한다.

스프링 부트와 같은 스프링 기반 애플리케이션에서는 @Entity 어노테이션을 사용하여 엔티티 클래스를 정의하고 JPA를 통해 해당 엔티티를 데이터베이스와 매핑한다.

이렇게 하면 객체 지향적인 방식으로 데이터를 다루면서도 데이터베이스와의 효율적인 상호작용을 달성할 수 있다.

@Enumerated

JPA 엔티티 클래스에서 Enum 타입을 매핑할 때 사용되는 어노테이션이다.

이 어노테이션은 열거형 상수를 데이터베이스 테이블의 열로 매핑하거나

역으로 데이터베이스에서 가져온 값을 열거형 상수로 변환하는 데 도움을 준다.

EnumType.ORDINAL

열거형 상수의 순서 값을 데이터베이스에 저장한다.

열거형 상수는 0부터 시작하는 순서에 따라 저장된다.

이 방식은 데이터베이스의 크기를 줄이지만, 열거형 상수 순서를 변경하거나

새로운 상수를 추가하는 경우 문제가 발생할 수 있다.

EnumType.STRING

열거형 상수의 이름을 데이터베이스에 저장한다.

열거형 상수의 이름은 문자열로 저장되므로 데이터베이스의 가독성이 높아진다.

이 방식은 열거형 상수의 순서를 변경해도 안전하다.

import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;

@Entity
public class Person {
    @Id
    private Long id;
    private String name;

    @Enumerated(EnumType.STRING) // EnumType.ORDINAL을 사용할 수도 있음
    private Gender gender;

    // 게터, 세터 및 생성자는 생략
}

public enum Gender {
    MALE,
    FEMALE,
    OTHER
}

Gender 열거형을 @Enumerated 어노테이션을 사용하여 문자열로 매핑하도록 지정했다.

이것은 데이터베이스에 “MALE”, “FEMALE”, “OTHER”와 같은 문자열 값으로 저장된다.

@GetMapping

HTTP GET 요청을 처리하는 컨트롤러 메서드에 적용되는 어노테이션이다.

즉, 클라이언트가 웹 브라우저 주소창에 URL을 입력하고 엔터키를 누르면 발생하는 GET 요청을 처리하는 데 사용된다.

@GetMapping("/example")
public String exampleMethod() {
    // 메서드 로직
    return "example-view"; // 뷰 이름 반환
}

// /example 경로로 들어오는 GET 요청을 처리하는 exampleMethod라는 컨트롤러 메서드를 정의하고 있다.

@GetMapping 어노테이션은 보통 목록 조회, 상세 정보 조회, 홈 페이지와 같이 HTTP GET 요청에 대한 처리를 담당하는 메서드에 적용된다.

요청된 URL과 일치하는 메서드가 실행되고, 그 결과를 클라이언트에 반환하게 된다.

HTTP GET 요청 처리

@GetMapping 어노테이션을 메서드에 적용하면 해당 메서드는 HTTP GET 요청을 처리한다.

다른 HTTP 메서드(GET, POST, PUT, DELETE 등)를 처리하는 어노테이션과 함께 사용할 수 있다.

URL 매핑

@GetMapping 어노테이션은 메서드를 특정 URL에 매핑한다.

이 URL은 메서드가 처리하는 요청의 엔드포인트로 사용된다.

@GetMapping("/products")
public String listProducts(Model model) {
    // 상품 목록을 조회하고 View로 전달하는 로직
    return "product/list";
}
// /products 경로로 들어오는 GET 요청을 listProducts 메서드가 처리한다.

파라미터 전달

@GetMapping 어노테이션을 사용한 메서드에는 파라미터를 전달할 수 있다.

주로 URL 경로나 요청 파라미터를 받아 처리하는 데 사용다.

@GetMapping("/products/{productId}")
public String getProduct(@PathVariable Long productId, Model model) {
    // productId를 이용하여 특정 상품 정보를 조회하고 View로 전달하는 로직
    return "product/detail";
}
// {productId}는 경로 변수로 사용되며, 
// 클라이언트가 /products/123과 같은 URL을 요청하면 getProduct 메서드에서
// productId 변수에 123 값을 전달받게 된다.

Model 객체

Model 객체를 메서드의 파라미터로 받아서 뷰 템플릿에 데이터를 전달할 수 있다.

이를 통해 컨트롤러에서 처리한 데이터를 뷰에서 표시할 수 있다.

@GetMapping("/products")
public String listProducts(Model model) {
    List<Product> products = productService.getAllProducts();
    model.addAttribute("products", products);
    return "product/list";
}

// model.addAttribute("products", products)를 통해 
// products라는 이름으로 상품 목록 데이터를 뷰로 전달한다.

@Getter, @Setter

자바 클래스의 getter와 setter 메서드를 자동으로 생성해주는 기능을 제공한다.

이 어노테이션을 사용하면 반복적인 getter와 setter 메서드를 작성하지 않고도 필드에 접근하고 값을 설정할 수 있다.

import lombok.Getter;

public class Example {
    @Getter
    private int value;
}
import lombok.Setter;

public class Example {
    @Setter
    private int value;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Member {
    private long memberId;
    private String email;
    private String name;
    private String phone;
}

@GeneratedValue

Java Persistence API(JPA)에서 엔티티 클래스의 기본 키 필드의 값을 생성하는 방법을 지정하는데 사용된다.

데이터베이스 테이블에서의 자동 증가 (Auto-increment) 열, 시퀀스 (Sequence) 또는 기타 방법을 사용하여 기본 키 값을 생성할 때 주로 활용된다.

엔티티 매핑 [더보기] <- 여기서 더 자세한 내용을 볼 수 있다.

AUTO

데이터베이스에 따라 자동으로 생성 방식을 선택한다.

대부분의 데이터베이스에서는 자동 증가 열을 생성하게 된다.

IDENTITY

데이터베이스의 IDENTITY 컬럼을 사용하여 기본 키 값을 생성한다.

이 컬럼은 일반적으로 자동 증가 열로 구성된다.

SEQUENCE

데이터베이스 시퀀스를 사용하여 기본 키 값을 생성한다.

이 옵션은 일부 데이터베이스 시스템에서 사용된다.

TABLE

데이터베이스에 특별한 테이블을 사용하여 기본 키 값을 생성한다.

이 옵션도 일부 데이터베이스에서 사용된다.

@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String department;
    // ...
}

위의 예시에서 @GeneratedValue 어노테이션은 strategy 속성을 GenerationType.Identity로 설정하였기 때문에,

데이터베이스에서 자동 증가 열을 사용하여 id 필드 값을 생성한다.

@interface

사용자 정의 어노테이션을 생성할 때 사용되는 키워드이다.

어노테이션은 소스 코드에 메타데이터를 추가하는 방법 중 하나이며,

이를 통해 프로그램의 동작을 제어하거나 설명하는데 사용된다.

@Interface를 사용하여 사용자 정의 어노테이션을 만들 때,

어노테이션의 이름과 그 어노테이션에 대한 속성을 정의할 수 있다.

속성은 해당 어노테이션을 사용할 때 값으로 전달되며, 이를 통해 어노테이션의 동작을 조절하거나 정보를 저장할 수 있다.

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME) // 어노테이션 정보를 런타임까지 유지하도록 지정
@Target(ElementType.METHOD) // 어노테이션을 메서드에 적용할 수 있도록 지정
public @interface MyAnnotation {
    // 어노테이션의 속성 정의
    String value() default ""; // 기본값을 지정할 수 있음
    int count() default 0;
}

위의 코드에서 @MyAnnotation은 사용자 정의 어노테이션을 정의한 것이다.

이 어노테이션은 value 와 count 두 개의 속성을 가지고 있으며, 이 어노테이션을 메서드에 적용할 수 있도록 지정되었다.

사용자 정의 어노테이션을 만들면, 이를 다른 클래스나 메서드에 적용하여 특정한 동작을 수행하거나 메타데이터를 제공할 수 있다.

예를 들어, 위의 @MyAnnotation을 사용하여 메서드에 어노테이션을 적용하면 해당 메서드에 특별한 의미나 동작을 부여할 수 있다.

public class MyClass {
    @MyAnnotation(value = "Hello", count = 5)
    public void myMethod() {
        // 메서드 내용
    }
}

@Min, @Max

자바 빈 유효성 검사(Java Bean Validation) 스펙(JSR-380)의 일부로,

숫자 필드의 값이 주어진 범위 내에 있는지를 검사하는 데 사용된다.

@Min

숫자 필드의 값이 특정 최솟값 이상이어야 함을 나타낸다.

주로 양수의 최솟값을 지정하는 데 사용된다.

@Min(value = 18, message = "나이는 18세 이상이어야 합니다.")
private int age;

@Max

숫자 필드의 값이 특정 최댓값 이하이어야 함을 나타낸다.

주로 양수의 최댓값을 지정하는 데 사용된다.

@Max(value = 100, message = "나이는 100세 이하여야 합니다.")
private int age;

@NoArgsConstructor

파라미터가 없는 기본 생성자를 자동으로 생성해주는 기능을 제공한다.

이 어노테이션을 사용하면 클래스 내에 아무런 생성자가 없을 때,

컴파일러가 자동으로 디폴트 생성자를 생성해주는 것과 같은 효과를 얻을 수 있다.

주로 자바 빈 규약을 따르는 클래스나 JPA 엔티티 클래스를 작성할 때 사용된다.

import lombok.NoArgsConstructor;

@NoArgsConstructor
public class Example {
    private int id;
    private String name;
}

위의 코드에서는 Example 클래스에 기본 생성자가 없지만,

@NoArgsConstructor 어노테이션을 사용하여 컴파일시 자동으로 기본 생성자가 생성된다.

Example example = new Example();

@PostMapping

HTTP POST 요청을 처리하는 컨트롤러 메서드에 적용되는 어노테이션이다.

HTTP POST 요청은 클라이언트에서 서버로 데이터를 제출할 때 사용되며, 주로 데이터 생성 또는 업데이트와 관련된 작업을 수행하는 메서드에 사용한다.

@PostMapping("/create")
public String createResource(@RequestBody Resource resource) {
    // POST 요청으로 받은 데이터를 처리하는 로직
    return "success-view"; // 성공 페이지 뷰 이름 반환
}

@PostMapping 어노테이션은 주로 데이터 생성 또는 업데이트와 관련된 작업을 처리하는 메서드에 적용된다.

클라이언트가 서버에 데이터를 전송하고자 할 때 사용되며, 이를 통해 서버 측에서 데이터를 처리하고 응답을 반환한다.

HTTP POST 요청 처리

@PostMapping 어노테이션은 메서드를 HTTP POST 요청을 처리하는 메서드로 지정한다.

이 메서드는 클라이언트에서 데이터를 서버로 보낼 때 호출된다.

URL 매핑

@PostMapping 어노테이션을 사용하면 메서드를 특정 URL에 매핑할 수 있다.

이 URL은 메서드가 처리하는 요청의 엔드포인트로 사용된다.

@PostMapping("/products")
public String createProduct(@ModelAttribute Product product) {
    // 상품 생성 로직
    productService.createProduct(product);
    return "redirect:/products";
}

// /products 경로로 POST 요청이 오면 createProduct 메서드가 실행된다.

요청 데이터 처리

@ModelAttribute 어노테이션을 사용하여 클라이언트로부터 전송된 데이터를 메서드의 파라미터로 받아 처리할 수 있다.

주로 HTML 폼에서 입력한 데이터를 받아와서 객체로 변환하거나 데이터베이스에 저장하는 용도로 사용된다.

@PostMapping("/products")
public String createProduct(@ModelAttribute Product product) {
    // 상품 생성 로직
    productService.createProduct(product);
    return "redirect:/products";
}

// @ModelAttribute 어노테이션을 사용하여 클라이언트에서 전송한 상품 
// 데이터를 Product 객체로 변환하여 처리한다.

HTTP 응답

@PostMapping 메서드는 주로 작업을 완료한 후 적절한 HTTP 응답을 생성하여 클라이언트에 반환한다.

이 때, 주로 리다이렉션(Redirect)을 사용하여 다른 페이지로 이동시킨다.

@PostMapping("/products")
public String createProduct(@ModelAttribute Product product) {
    // 상품 생성 로직
    productService.createProduct(product);
    return "redirect:/products";
}

// 상품을 생성한 후 /products 페이지로 리다이렉트하여 상품 목록을 표시한다.

@PathVariable

스프링 MVC에서 사용되며, 웹 요청 URL의 일부를 추출하여 컨트롤러 메서드의 파라미터로 전달하는 데 사용된다.

주로 RESTful 웹 애플리케이션에서 동적인 URL을 처리하는 데 활용된다.

/products/{productId} URL이 있다고 가정해보면.

이 URL은 “products”라는 경로 다음에 변수 productId가 있는 것을 나타낸다.

이때, @PathVariable을 사용하여 productId 값을 추출할 수 있다.

아래는 간단한 컨트롤러 메서드의 예시이다.

@GetMapping("/products/{productId}")
public ResponseEntity<Product> getProductById(@PathVariable Long productId) {
    // productId를 사용하여 해당 상품 정보를 가져오는 로직
    Product product = productService.getProductById(productId);
    
    if (product == null) {
        return ResponseEntity.notFound().build();
    }
    
    return ResponseEntity.ok(product);
}

@PathVariable 어노테이션을 사용하여 productId를 추출하고,

이를 통해 해당 상품 정보를 가져오는 메서드를 호출한다.

클라이언트가 /products/123과 같은 URL로 요청을 보내면, productId 파라미터는 123의 값을 갖게 된다.

@PathVariable 어노테이션은 다양한 데이터 타입을 지원하며,

복잡한 URL 패턴에서 여러 경로 변수를 추출하는 데도 사용할 수 있다.

예를 들어, /products/{category}/{productId}와 같은 URL에서 두 개 이상의 경로 변수를 추출할 수 있다.

@GetMapping("/products/{category}/{productId}")
public ResponseEntity<Product> getProductByCategoryAndId(
    @PathVariable String category,
    @PathVariable Long productId
) {
    // category와 productId를 사용하여 해당 상품 정보를 가져오는 로직
    Product product = productService.getProductByCategoryAndId(category, productId);
    
    if (product == null) {
        return ResponseEntity.notFound().build();
    }
    
    return ResponseEntity.ok(product);
}

@Qualifier

스프링에서 빈(bean)을 주입할 때 여러 후보 빈 중에서 어떤 빈을 선택할지 지정하는 데 사용되는 어노테이션이다.

@Autowired 어노테이션과 함께 주로 사용되며, 빈의 이름을 이용하여 의존성 주입을 명시적으로 지정할 때 유용하다.

@Qualifier 어노테이션을 사용하면 여러 후보 빈 중에서 특정한 빈을 선택하는 작업이 가능하며, 이는 같은 타입의 빈이 여러 개 존재할 때 주입 대상 빈을 명시하는 데 유용하다.

아래와 같이 @Qualifier 어노테이션을 사용하여 의존성 주입 대상 빈을 선택할 수 있다.

@Service
public class OrderService {
    private final PaymentGateway paymentGateway;

    @Autowired
    public OrderService(@Qualifier("paypalGateway") PaymentGateway paymentGateway) {
        this.paymentGateway = paymentGateway;
    }

    // ...
}

위의 예시에서 OrderService 클래스의 생성자에서 PaymentGateway 타입의 빈을 주입할 때 @Qualifier("paypalGateway")를 사용하여 “paypalGateway”라는 이름의 빈을 명시적으로 선택하도록 지정하고 있다.

또 다른 방법으로, 빈 정의에서 @Qualifier를 사용하여 특정 빈에 이름을 부여하고, 주입할 때 해당 이름을 사용하는 방법도 있다.

@Configuration
public class AppConfig {
    @Bean
    @Qualifier("paypalGateway")
    public PaymentGateway paypalPaymentGateway() {
        return new PaypalPaymentGateway();
    }

    @Bean
    @Qualifier("stripeGateway")
    public PaymentGateway stripePaymentGateway() {
        return new StripePaymentGateway();
    }
}

이렇게 빈의 이름을 부여하고, @Autowired 어노테이션을 사용할 때 @Qualifier와 함께 해당 이름을 지정하면 해당 빈이 주입된다.

@RestController

웹 애플리케이션에서 사용되는 컨트롤러 클래스에 적용되는 어노테이션이다.

이 어노테이션은 주로 RESTful 웹 서비스를 개발할 때 사용되며,

컨트롤러 클래스의 메서드가 HTTP 요청에 응답하여 데이터를 제공하는 역할을 한다.

@RestController 어노테이션은 @Controller@ResponseBody 어노테이션을 함께 사용하는 것과 동일한 효과를 갖는다.

@Controller 클래스에서 각 메서드에 @ResponseBody 어노테이션을 추가하는 대신, @RestController를 클래스 레벨에 적용하면 모든 메서드에 자동으로 @ResponseBody가 적용한다.

HTTP 요청 처리

@RestController는 HTTP GET, POST, PUT, DELETE 등 다양한 HTTP 요청 메서드에 대한 요청을 처리한다.

데이터 반환

주로 JSON 또는 XML 형식의 데이터를 반환하며, 이를 통해 클라이언트와 서버 간의 데이터 교환을 수행한다.

@ResponseBody 자동 적용

@RestController 클래스에는 @ResponseBody가 자동으로 적용되므로, 메서드에서 데이터를 반환할 때 HTTP 응답 본문으로 직접 데이터를 보낼 수 있다.

RESTful 경로 지원

@RequestMapping 어노테이션을 사용하여 RESTful 경로를 지원하며, 각 경로에 대한 요청을 처리할 수 있다.

스프링 컨테이너 관리

@RestController 어노테이션을 사용한 클래스도 스프링 컨테이너에 등록되어 빈으로 관리된다.

@RestController
@RequestMapping("/api")
public class MyRestController {

    @GetMapping("/data")
    public ResponseEntity<String> getData() {
        String data = "Hello, REST!";
        return new ResponseEntity<>(data, HttpStatus.OK);
    }
}

위의 코드에서 @RestController 어노테이션이 적용된 MyRestController 클래스는 “/api/data” 경로로 들어오는 GET 요청을 처리하며,

“Hello, REST!”라는 문자열을 JSON 형식으로 응답한다.

이러한 방식으로 RESTful 웹 서비스를 제공할 수 있다.

@Repository

영속성(persistence) 계층을 나타내는 빈(Bean) 클래스에 사용되는 어노테이션이다.

주로 데이터 액세스 레이어(Data Access Layer)에서 사용된다.

이 어노테이션을 사용하여 클래스를 빈으로 등록하고, 데이터베이스와의 상호 작용을 처리하는 DAO(Data Access Object) 클래스를 나타낸다.

컴포넌트 스캔

@Repository 어노테이션이 적용된 클래스들은 스프링의 컴포넌트 스캔(Component Scan)을 통해 자동으로 스프링 컨테이너에 빈으로 등록된다.

이렇게 등록된 빈은 스프링이 관리하며, 다른 빈에서 주입하여 사용할 수 있다.

예외 변환

@Repository 어노테이션이 적용된 클래스들은 데이터 액세스 중 발생하는 예외를 스프링의 DataAccessException으로 변환한다.

이로써 데이터 액세스 관련 예외를 일관된 방식으로 처리하고, 데이터베이스 예외를 런타임 예외로 감싸지 않아도 된다.

의존성 주입(Dependency Injection)

@Repository 어노테이션을 사용하면 해당 클래스의 인스턴스가 스프링 컨테이너에 의해 관리되므로, 다른 스프링 빈과의 의존성 주입이 용이해진다.

데이터 액세스 레이어 클래스들은 주로 서비스(Service)나 컨트롤러(Controller) 계층에서 사용되며, 이러한 계층 간의 협력을 쉽게 구현할 수 있다.

정확하게 말하면 다음과 같다.

@Repository 어노테이션은 주로 데이터 액세스 레이어 에서 데이터베이스와의 상호 작용을 처리하는 클래스를 나타내기 위해 사용된다.

이 어노테이션을 사용하여 클래스를 Spring 빈으로 등록한다.

이는 Spring 컨테이너에서 해당 클래스의 인스턴스를 관리하고 주입(DI)을 통해 다른 빈과 협력할 수 있도록 한다.

@Repository 어노테이션이 주로 DAO 클래스에 적용된다.

DAO 클래스는 데이터베이스와의 상호 작용을 담당하며, 데이터 검색, 삽입, 업데이트, 삭제 등의 데이터 액세스 작업을 수행한다.

@Repository
public class UserRepository {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public User getUserById(Long id) {
        String sql = "SELECT * FROM users WHERE id = ?";
        return jdbcTemplate.queryForObject(sql, new Object[]{id}, new UserRowMapper());
    }

    public void saveUser(User user) {
        String sql = "INSERT INTO users (id, username, email) VALUES (?, ?, ?)";
        jdbcTemplate.update(sql, user.getId(), user.getUsername(), user.getEmail());
    }
}

@Repository 어노테이션이 적용된 UserRepository 클래스는 스프링 컨테이너에 의해 빈으로 관리되며, 데이터베이스와 상호 작용하는 메서드를 제공한다.

@Autowired 어노테이션을 사용하여 JdbcTemplate 빈을 주입받아 데이터베이스 액세스를 수행하고, 데이터베이스 관련 예외는 스프링의 DataAccessException으로 처리된다.

@RequestMapping

HTTP 요청과 어떤 메서드가 연결되어야 하는지를 지정하는 데 사용되는 어노테이션이다.

이 어노테이션을 사용하여 컨트롤러 클래스의 메서드가 어떤 URL에 대한 요청을 처리할지를 설정한다.

@RequestMapping 어노테이션은 클래스 수준과 메서드 수준에서 모두 사용할 수 있다.

value 또는 path

요청을 처리할 URL 패턴을 지정한다.

이 패턴은 문자열 형태로 지정하며, 다양한 경로 및 변수를 포함할 수 있다.

여러 개의 패턴을 배열로 지정할 수도 있다.

@RequestMapping("/products") // 단일 URL 패턴
@RequestMapping(value = {"/products", "/items"}) // 다중 URL 패턴

method

HTTP 요청 메서드를 지정한다.

기본적으로 모든 HTTP 메서드에 대한 처리가 이뤄진다.

원하는 HTTP 메서드를 지정하여 요청을 처리할 수 있다.

@RequestMapping(value = "/create", method = RequestMethod.POST) // POST 요청만 처리

params

특정한 요청 파라미터의 존재 여부나 값에 따라 요청을 처리할 수 있다.

@RequestMapping(value = "/search", params = "keyword") // keyword 파라미터가 있는 요청만 처리

headers

요청 헤더 값에 따라 요청을 처리할 수 있다.

@RequestMapping(value = "/secure", headers = "X-Auth-Token=abc123") // X-Auth-Token 헤더가 일치하는 요청만 처리

consumes

클라이언트가 전송한 컨텐츠 타입에 따라 요청을 처리할 수 있다.

@RequestMapping(value = "/data", consumes = "application/json") // JSON 데이터를 요청으로 받는 경우만 처리

produces

서버가 생성한 컨텐츠 타입에 따라 요청을 처리할 수 있다.

@RequestMapping(value = "/data", consumes = "application/json") // JSON 데이터를 요청으로 받는 경우만 처리

params, headers, consumes, produces 등의 조합

이러한 속성들을 조합하여 더 복잡한 요청 조건을 지정할 수 있다.

@RequestMapping(value = "/data", consumes = "application/json") // JSON 데이터를 요청으로 받는 경우만 처리
@Controller
@RequestMapping("/products")
public class ProductController {

    @GetMapping
    public String listProducts(Model model) {
        // 상품 목록을 조회하고 View로 전달하는 로직
        return "product/list";
    }
}

@RequestMapping 어노테이션을 사용하면 스프링은 해당 메서드를 해당 URL 및 요청 조건에 매핑하여 요청을 처리하고, 결과를 클라이언트에 반환한다.

@ResponseBody

컨트롤러 메서드가 HTTP 응답의 본문(body)을 직접 작성할 때 사용되는 어노테이션이다.

이 어노테이션을 사용하면 메서드가 반환하는 데이터가 뷰 템플릿을 통해 렌더링되지 않고, HTTP 응답의 본문으로 직접 전송된다.

@ResponseBody 어노테이션을 사용하는 메서드는 일반적으로 JSON 또는 XML과 같은 데이터 형식을 생성하여 클라이언트에 반환하는 데 사용된다.

이를 통해 RESTful 웹 서비스나 AJAX 요청에 응답할 수 있다.

@RestController
public class MyRestController {

    @GetMapping("/api/data")
    @ResponseBody
    public Map<String, String> getApiData() {
        Map<String, String> data = new HashMap<>();
        data.put("message", "Hello, World!");
        return data;
    }
}

/api/data 경로로 GET 요청이 들어오면, getApiData 메서드가 호출되고 이 메서드는 JSON 형식의 데이터를 HTTP 응답 본문으로 반환한다.

@ResponseBody 어노테이션은 기본적으로 HTTP 응답의 본문 형식을 JSON으로 설정한다.

그러나 다른 형식의 데이터를 반환하려면 produces 속성을 사용하여 명시적으로 설정할 수 있다.

예를 들어 XML 형식으로 데이터를 반환하려면 다음과 같이 설정할 수 있다.

@GetMapping("/api/data-xml", produces = MediaType.APPLICATION_XML_VALUE)
@ResponseBody
public MyXmlData getApiDataXml() {
    MyXmlData xmlData = new MyXmlData();
    xmlData.setMessage("Hello, XML!");
    return xmlData;
}

@RestController 어노테이션을 클래스에 적용하면 해당 컨트롤러의 모든 메서드에 @ResponseBody 어노테이션을 따로 붙이지 않아도 된다.

이렇게하면 클래스 수준에서 기본적으로 JSON 형식의 데이터를 반환한다고 설정된다.

@RequestBody

HTTP 요청의 본문(body)에 포함된 데이터를 자바 객체로 매핑하기 위해 사용된다.

주로 웹 애플리케이션에서 클라이언트가 POST 또는 PUT 요청을 통해 JSON 또는 XML 형식으로 데이터를 전송할 때 사용된다.

요청 본문과 객체 간의 매핑

클라이언트의 HTTP 요청 본문에 포함된 데이터를 지정한 자바 객체로 자동 매핑한다.

이를 통해 HTTP 요청에서 데이터를 추출하고 자바 객체로 변환할 수 있다.

주로 POST 및 PUT 요청과 함께 사용

주로 POST나 PUT요청과 함께 사용되며,

클라이언트가 서버로 데이터를 보낼 때 요청 본문에 데이터를 포함하여 전송할 때 유용하다.

JSON, XML 및 기타 형식과 호환

주로 JSON 또는 XML 형식으로 전송되는 데이터와 호환된다.

스프링은 HTTP 요청의 Content-Type 헤더를 기반으로 적절한 메시지 컨버터를 선택하여 요청 본문의 데이터를 자바 객체로 변환한다.

메서드 매개변수로 사용

메서드의 매개변수로 사용된다.

메서드의 매개변수에 @RequestBody 어노테이션을 추가하면 해당 매개변수가 요청 본문의 데이터를 수신하는 역할을 한다.

@RestController
@RequestMapping("/api")
public class MyController {

    @PostMapping("/create")
    public ResponseEntity<String> createItem(@RequestBody Item newItem) {
        // 클라이언트가 보낸 JSON 데이터가 Item 객체로 자동 매핑됨
        // newItem을 이용하여 데이터 처리
        return ResponseEntity.ok("Item created successfully");
    }
}

@RequestParam

스프링 MVC에서 사용되며, HTTP 요청 파라미터를 컨트롤러 메서드의 파라미터로 바인딩하기 위해 사용된다.

웹 요청에서 GET 또는 POST 매개변수를 추출하고 이를 컨트롤러 메서드에서 사용할 수 있도록 도와준다.

일반적으로 웹 폼(form)에서 전송된 데이터나 URL 쿼리 문자열(query string)에서 파라미터를 추출할 때 @RequestParam 어노테이션을 사용한다.

예를 들어, /products?id=123 URL이 있다고 가정해보겠다.

이 URL에서 “id”라는 매개변수 값을 추출하고자 할 때 @RequestParam을 사용할 수 있다.

@GetMapping("/products")
public ResponseEntity<Product> getProductById(@RequestParam Long id) {
    // id를 사용하여 해당 상품 정보를 가져오는 로직
    Product product = productService.getProductById(id);
    
    if (product == null) {
        return ResponseEntity.notFound().build();
    }
    
    return ResponseEntity.ok(product);
}

@RequestParam 어노테이션을 사용하여 “id” 파라미터 값을 추출하고, 이를 통해 해당 상품 정보를 가져온다.

클라이언트가 /products?id=123과 같은 URL로 요청을 보내면, “id” 파라미터의 값은 123이 된다.

required

기본적으로 true로 설정되어 있으며, 파라미터가 반드시 존재해야 함을 나타낸다.

만약 요청에 해당 파라미터가 없으면 예외가 발생한다.

defaultValue

파라미터의 기본값을 지정할 수 있다.

요청에 해당 파라미터가 없을 경우 이 기본값이 사용된다.

name

요청에서 파라미터의 이름이 메서드의 파라미터 이름과 다른 경우 사용한다.

예를 들어, @RequestParam(name = "productId") Long id와 같이 사용할 수 있다.

@RequestHeader

스프링 MVC에서 사용되며, HTTP 요청 헤더 값을 컨트롤러 메서드의 파라미터로 바인딩하기 위해 사용된다.

즉, 웹 요청의 헤더 정보를 컨트롤러 메서드에서 활용할 수 있도록 도와준다.

HTTP 요청은 다양한 헤더를 가질 수 있다.

예를 들어, User-Agent, Authorization, Content-Type, Accept-Language 등의 헤더는 일반적으로 웹 요청과 함께 전송된다.

@RequestHeader 어노테이션을 사용하면 이러한 헤더 값을 추출하고 컨트롤러 메서드에서 사용할 수 있다.

@GetMapping("/user-agent")
public ResponseEntity<String> getUserAgent(@RequestHeader("User-Agent") String userAgent) {
    return ResponseEntity.ok("User-Agent: " + userAgent);
}

@RequestHeader("User-Agent") 어노테이션을 사용하여 User-Agent 헤더의 값을 추출하고, 이를 문자열 변수 userAgent에 바인딩한다.

그리고 이 값을 클라이언트에게 응답으로 반환한다.

@RequestHeader 어노테이션은 헤더의 이름을 지정하고 해당 헤더의 값을 파라미터로 바인딩하는 데 사용된다.

이렇게 추출한 헤더 값을 컨트롤러 메서드에서 활용하여 다양한 작업을 수행할 수 있다.

또한 @RequestHeader 어노테이션은 다양한 속성을 가지고 있어서, 필수 여부, 기본값, 파라미터 이름 등을 지정할 수 있다.

이러한 속성을 활용하여 더 세밀한 설정을 할 수 있다.

@Retention

자바 어노테이션의 유지 정책(Annotation Retention Policy)을 지정하는데 사용되는 메타 어노테이션 중 하나이다.

어노테이션이 언제 유지되는지를 명시적으로 지정할 때 이 어노테이션을 사용한다.

RetentionPolicy.SOURCE

소스 코드 레벨에서만 어노테이션 정보가 유지된다.

컴파일 후 클래스 파일에는 어노테이션 정보가 포하모디지 않는다.

따라서 런타임 시점에는 해당 어노테이션 정보를 사용할 수 없다.

주로 코드 생성기와 같이 컴파일 시 코드 생성에 활용되는 경우에 사용된다.

RetentionPolicy.CLASS

클래스 파일(바이트코드)에 어노테이션 정보가 유지된다.

런타임 시점에는 해당 어노테이션 정보에 접근할 수 없지만, 리플렉션(reflection)을 통해 클래스 파일에서 어노테이션 정보를 읽어올 수 있다.

이는 대부분의 경우에 사용되는 기본 유지 정책이다.

RetentionPolicy.RUNTIME

클래스 파일에 어노테이션 정보가 유지되며, 런타임 시점에 어노테이션 정보를 읽고 처리할 수 있다.

이 유지 정책을 사용하면 런타임 시점에 리플렉션을 통해 어노테이션 정보를 동적으로 확인하고 활용할 수 있다.

이 유지 정책은 주로 프레임워크와 라이브러리 개발 시 사용된다.

@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    // 어노테이션 내용
}

@SpringBootApplication

스프링 부트 애플리케이션을 정의하고 구성하는데 사용되는 메타 어노테이션이다.

스프링 부트 애플리케이션을 시작할 때 사용하는 어노테이션으로, 메인 애플리케이션 클래스에 선언한다.

이 어노테이션은 @Configuration, @EnableAutoConfiguration, @ComponentScan 어노테이션의 기능을 포함한다.

@SpringBootApplication
public class MySpringBootApplication {

    public static void main(String[] args) {
        SpringApplication.run(MySpringBootApplication.class, args);
    }
}

@Service

스프링 프레임워크에서 서비스 레이어(Service Layer)의 구성 요소인 클래스를 식별하는 데 사용되는 어노테이션이다.

서비스 레이어는 비즈니스 로직을 처리하고 제공하는 데 사용되며, 주로 서비스 클래스들이 이 어노테이션을 사용한다.

컴포넌트 스캔

@Service 어노테이션이 적용된 클래스들은 스프링의 컴포넌트 스캔(Component Scan)을 통해 자동으로 스프링 컨테이너에 빈으로 등록된다.

따라서 @Service 어노테이션이 붙은 클래스를 직접 빈으로 설정할 필요가 없다.

의존성 주입(Dependency Injection)

@Service 어노테이션을 사용하면 해당 클래스의 인스턴스가 스프링 컨테이너에 의해 관리되므로, 다른 스프링 빈과의 의존성 주입이 용이해진다.

서비스 클래스는 주로 리포지토리나 DAO(Data Access Object)와 같은 다른 컴포넌트와 협력하여 비즈니스 로직을 수행한다.

트랜잭션 관리

@Service 어노테이션이 적용된 클래스들은 스프링의 트랜잭션 관리를 받을 수 있다.

이는 @Transactional 어노테이션과 함께 사용하여 데이터베이스 트랜잭션을 처리하거나 롤백 등의 트랜잭션 관련 작업을 수행할 수 있다.

@Service
public class UserService {
    
    @Autowired
    private UserRepository userRepository;

    @Transactional
    public User getUserById(Long id) {
        return userRepository.findById(id).orElse(null);
    }

    @Transactional
    public void saveUser(User user) {
        userRepository.save(user);
    }
}

@Service 어노테이션이 적용된 UserService 클래스는 스프링 컨테이너에 의해 빈으로 관리되며, 데이터베이스 관련 로직을 수행한다.

@Autowired 어노테이션을 사용하여 UserRepository 빈을 주입받고, @Transactional 어노테이션을 사용하여 트랜잭션 관리를 수행한다.

@Table

JPA(Java Persistence API) 엔티티 클래스와 데이터베이스 테이블 간의 매핑을 정의하기 위해 사용되는 어노테이션 중 하나이다.

이 어노테이션을 사용하여 엔티티 클래스가 매핑하려는 특정 데이터베이스 테이블의 속성을 지정할 수 있다.

name

매핑할 데이터베이스 테이블의 이름을 지정한다.

기본적으로 엔티티 클래스의 이름을 사용하지만, 특별한 경우에는 다른 이름을 사용하고자 할 때 이 속성을 설정한다.

schema

데이터베이스 스키마의 이름을 지정한다.

이 속성을 사용하여 엔티티가 속한 스키마를 지정할 수 있다.

catalog

데이터베이스 카탈로그의 이름을 지정한다.

엔티티가 특정 카탈로그에 속하는 경우 이 속성을 사용하여 지정할 수 있다.

uniqueConstraints

엔티티에 대한 고유 제약 조건(unique constraint)을 정의할 때 사용한다.

고유 제약 조건은 엔티티 클래스의 여러 열에 대한 고유성을 지정할 때 유용하다.

@Table 어노테이션을 사용하여 엔티티 클래스를 데이터베이스 테이블과 매핑하는 예시이다.

@Entity
@Table(name = "products", schema = "my_schema", catalog = "my_catalog",
    uniqueConstraints = @UniqueConstraint(columnNames = {"product_code", "product_name"}))
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "product_id")
    private Long id;

    @Column(name = "product_code", unique = true)
    private String code;

    @Column(name = "product_name")
    private String name;

    @Column(name = "price")
    private double price;

    // Getter와 Setter 메서드, 기타 필드 및 메서드들
}

@Table 어노테이션을 사용하여 Product 엔티티 클래스를 products 테이블과 매핑하고,

테이블의 스키마는 my_schema, 카탈로그는 my_catalog로 지정하였다.

또한 uniqueConstraints 속성을 사용하여 product_codeproduct_name 열에 대한 고유 제약 조건을 정의하였다.

@Target

어노테이션이 적용될 수 있는 대상을 지정하기 위해 사용되는 메타 어노테이션 중 하나이다.

어노테이션이 어떤 요소에 적용될 수 있는지를 명시적으로 지정할 수 있다.

ElementType.TYPE - 클래스, 인터페이스, 열거형(enumeration) 등의 타입에 어노테이션을 적용할 수 있다.

ElementType.FIELD - 필드에 어노테이션을 적용할 수 있다.

ElementType.METHOD - 메서드에 어노테이션을 적용할 수 있다.

ElementType.PARAMETER - 메서드의 매개변수에 어노테이션을 적용할 수 있다.

ElementType.CONSTRUCTOR - 생성자에 어노테이션을 적용할 수 있다.

ElementType.LOCAL_VARIABLE - 지역 변수에 어노테이션을 적용할 수 있다.

ElementType.ANNOTATION_TYPE - 어노테이션 타입에 어노테이션을 적용할 수 있다.

ElementType.PACKAGE - 패키지에 어노테이션을 적용할 수 있다.

예를 들어, @Target 어노테이션을 사용하여 특정 어노테이션이 메서드에만 적용될 수 있도록 제한할 수 있다.

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyMethodAnnotation {
    // 어노테이션 내용
}

위 예시에서 @MyMethodAnnotation 어노테이션은 메서드에만 적용할 수 있도록 설정되어 있다.

이렇게 하면 클래스나 필드 등 다른 요소에는 적용할 수 없게 된다.

@ToString

클래스의 toString() 메서드를 자동으로 생성해주는 기능을 제공한다.

자바에서 toString() 메서드는 객체를 문자열로 표현하는데 사용된다.

객체를 출력하거나 디버깅 목적으로 사용될 때 매우 유용하다.

@ToString 어노테이션을 클래스에 적용하면,

해당 클래스의 필드들을 포함한 문자열을 반환하는 toString() 메서드가 자동으로 생성된다.

이 때, 필드들은 기본적으로 콤마(,)로 구분되어 문자열로 변환된다.

import lombok.ToString;

@ToString
public class Person {
    private String name;
    private int age;
}

위의 코드에서 @ToString 어노테이션을 사용하면 다음과 같은 toString() 메서드가 자동으로 생성된다.

@Override
public String toString() {
    return "Person(name=" + name + ", age=" + age + ")";
}

이제 Person객체를 출력하거나 로깅할 때, 자동으로 위와 같은 형태의 문자열로 변환된다.

public static void main(String[] args) {
    Person person = new Person();
    person.setName("John");
    person.setAge(30);

    System.out.println(person); // 출력: Person(name=John, age=30)
}

@Value

스프링에서 프로퍼티(property) 값을 주입하거나, 리터럴 값을 빈의 필드, 메서드 매개변수, 또는 생성자 매개변수에 주입하기 위해 사용되는 어노테이션이다.

이 어노테이션은 주로 설정 파일에서 설정 값을 읽어와서 빈에 주입할 때 사용된다.

@Value 어노테이션은 주로 @Component, @Service, @Repository, @Controller 등과 함께 사용되며,

스프링 컨테이너에서 빈으로 관리되는 클래스에서 값을 주입받을 때 편리하게 사용된다.

또한, 프로퍼티 값을 외부 설정 파일에서 관리하거나, 리터럴 값을 주입할 때 유용하다.

프로퍼티 값 주입

@Value("${app.server.host}")
private String serverHost;

${app.server.host}라는 프로퍼티 값을 serverHost 필드에 주입한다.

이 프로퍼티 값은 스프링 설정 파일(예: application.properties 또는 application.yml)에 정의되어 있어야 한다.

리터럴 값 주입

@Value("10")
private int maxConnections;

이 경우, maxConnections 필드에 직접 숫자 10이 주입된다.

SpEL (Spring Expression Language) 표현식 사용

@Value("#{systemProperties['java.home']}")
private String javaHome;

이 경우, SpEL 표현식을 사용하여 java.home 시스템 프로퍼티 값을 javaHome 필드에 주입한다.

@Valid

주로 자바 Bean Validation (또는 JSR 380) 스펙과 함께 사용되며, 객체나 필드의 유효성 검사를 수행하는데 사용된다.

스프링 프레임워크에서 주로 컨트롤러에서 HTTP 요청의 데이터를 검증할 때 사용된다.

import javax.validation.Valid;

@RestController
public class UserController {

    @PostMapping("/users")
    public ResponseEntity<String> createUser(@Valid @RequestBody User user) {
        // 유효성 검사를 통과한 경우에만 사용자 생성 로직을 수행
        // ...
        return ResponseEntity.ok("User created successfully.");
    }
}

@Valid 어노테이션은 @RequestBody 어노테이션이 지정된 User 객체에 대한 유효성 검사를 수행한다.

이것은 사용자가 HTTP POST 요청으로 데이터를 전송할 때 해당 데이터가 유효한지 확인하는 역할을 한다.

@Valid 어노테이션을 사용하면 다양한 검증 규칙을 설정할 수 있으며, 필요한 경우 커스텀 검증 로직을 정의할 수도 있다.

이를 통해 잘못된 데이터가 컨트롤러 메서드로 전달되는 것을 방지하고 안정성을 높일 수 있다.

Valid 어노테이션을 사용하려면 프로젝트에 Bean Validation 관련 라이브러리 (예: Hibernate Validator)를 포함시켜야 한다.

스프링 부트 프로젝트에서는 기본적으로 이러한 라이브러리가 함께 제공되므로 설정이 간단하다.

@Validated

유효성 검사를 적용하는 데 사용되는 어노테이션이다.

주로 스프링 MVC 컨트롤러의 메서드나 서비스 빈 클래스에 적용되며,

메서드 실행 시에 입력 데이터를 검즈앟고 유효성 검사 오류가 있는 경우 예외를 발생시킬 수 있다.

Hibernate Validator

@Validated 어노테이션을 사용하면 Hibernate Validator를 활용하여 객체 유효성 검사를 수행 할 수 있다.

Java Bean Validation (JSR-380)

스프링은 자바 빈 유효성 검사(Java Bean Validation) 스펙(JSR-380)과 호환되도록 @Validated 어노테이션을 지원한다.

이를 통해 빈 유효성 검사 어노테이션인 @NotNull, @Size, @Email 등을 사용하여 객체의 필드를 검증할 수 있다.

스프링의 BindingResult

@Validated 어노테이션을 사용하면 유효성 검사 결과를 BindingResult 객체로 받을 수 있다.

이를 통해 유효성 검사 오류 정보를 확인하고 처리할 수 있다.

@RestController
@RequestMapping("/user")
@Validated
public class UserController {

    @PostMapping("/create")
    public ResponseEntity<String> createUser(@RequestBody @Valid UserDTO userDTO) {
        // 유효성 검사를 통과한 경우
        // userDTO 객체는 유효한 데이터를 가지고 있음

        // 데이터 처리 로직
        // ...

        return ResponseEntity.ok("User created successfully");
    }
}

참고

@Controller와 @RestController의 차이점

반환 값의 의미

@Controller 어노테이션이 지정된 클래스의 메서드는 주로 웹 페이지를 렌더링 하는 데 사용된다.

메서드의 반환 값은 주로 뷰 템플릿 이름이나 모델 객체이다.

이렇게 반환된 데이터는 주로 HTML 뷰로 렌더링된다.

@RestController 어노테이션이 지정된 클래스의 메서드는 주로 데이터를 반환하기 위해 사용된다.

메서드의 반환 값은 주로 JSON, XML 또는 다른 데이터 형식이다.

이 데이터는 주로 웹 서비스의 API 응답으로 사용된다.

기본 응답 형식

@Controller로 정의된 메서드는 기본적으로 뷰 템플릿을 통해 HTML을 반환하므로, 브라우저가 이를 렌더링한다.

@RestController로 정의된 메서드는 기본적으로 JSON 형식의 데이터를 반환한다.

이 데이터는 클라이언트 애플리케이션이나 다른 웹 서비스에서 사용될 수 있다.

따라서 @Controller와 @RestController를 선택할 때는 웹 페이지를 반환할지 또는 데이터를 반환할지에 따라서 선택하면 된다.

RESTful API를 개발할 때는 주로 @RestController를 사용한다.


@PathVariable 과 @RequestParam의 차이점

두 어노테이션은 비슷한 역할을 하지만 웹 요청에서 다른 부분을 처리하는 데 사용된다.

@PathVariable

@GetMapping("/users/{userId}")
public ResponseEntity<User> getUserById(@PathVariable Long userId) {
    // userId 변수는 URI에서 추출됩니다.
    // 예: /users/123 에서 userId는 123이 됩니다.
    // ...
}

@RequestParam

@GetMapping("/users")
public ResponseEntity<List<User>> getUsersByNameAndAge(
    @RequestParam String name, @RequestParam int age) {
    // name과 age 변수는 쿼리 파라미터에서 추출됩니다.
    // 예: /users?name=John&age=30 에서 name은 "John", age는 30이 됩니다.
    // ...
}

@PathVariable은 URI 경로 변수를 읽어오고,

@RequestParam은 쿼리 파라미터를 읽어오는 데 사용된다.

댓글남기기