어노테이션 정리

LeeYulhee·2023년 9월 5일
0

📢 요청 처리와 매핑

👉 @RequestParam


  • URL 파라미터로 전달받은 value를 메서드의 파리마터로 받을 수 있게 해주는 어노테이션
  • 주로 쿼리 매개변수에서 값을 가져오는 데 사용
@GetMapping("/greet")
public String greet(@RequestParam(name = "name", required = false, defaultValue = "Guest") String name) {
    return "Hello, " + name + "!";
}

👉 @PathVariable


  • 변하는 값을 얻을 때 사용하는데, 매개변수와 Mapping URL 쪽에서 사용한 이름이 동일해야 함
  • URL 경로에서 값을 추출하여 메서드의 인자로 전달할 때 사용
@GetMapping("/greet/{name}")
public String greetPath(@PathVariable String name) {
    return "Hello, " + name + "!";
}

👉 @RequestBody


  • 클라이언트가 보낸 JSON이나 XML 등의 HTTP 요청 본문(body)을 자바 객체로 변환시키기 위해 컨트롤러의 메서드 파라미터 앞에 사용
@RestController
public class MyController {

    @PostMapping("/persons")
    public ResponseEntity<String> addPerson(@RequestBody Person person) {
        // person 객체는 클라이언트가 보낸 JSON 본문을 Person 객체로 변환한 것
        // ... 비즈니스 로직 처리 ...

        return ResponseEntity.ok("Person added successfully");
    }
}

class Person {
    private String name;
    private int age;
    // getters, setters, etc...
}

👉 @RequestMapping


  • 중복되는 URL 부분을 해당 어노테이션에 넣은 후 Mapping 부분에서 생략할 수 있음
  • @RequestMapping("/question")

👉 @GetMapping


  • HTTP GET 요청을 특정 메소드에 매핑하기 위해 사용
  • GET 요청
    • GET은 서버의 리소스에서 데이터를 요청할 때 사용(DB로 따지면 GET은 SELECT에 가깝고, 멱등(연산을 여러 번 적용해도 결과가 달라지지 않음 = 리소스를 조회하는 것이라))
    • GET은 요청을 전송할 때, 힐요한 데이터를 Body에 담지 않고, 쿼리스트링(URL 끝에 ?와 함께 이름과 값으로 쌍울 이루는 요청 파라미터)을 통해 전송
    • GET 요청은 캐시가 가능(GET을 통해 서버에 리소스를 요청할 때, 웹 캐시가 요청을 가로채 리소스를 다시 다운로드 하는 대신 리소스의 복사본 반환)함
    • GET 요청은 브라우저 히스토리에 남으며, 길이에 제한이 있고, 보안 상의 문제로 중요한 정보를 다루지 않는 것이 좋음

👉 @PostMapping


  • 매핑을 담당하는 역할로, HTTP POST 요청만 받아들일 경우에 사용
  • POST 요청
    • POST 요청은 서버의 리소스를 새로 생성하거나 업데이트할 때 사용(DB로 따지면 Create에 가깝고, 멱등X(리소스를 생성/업데이트에 사용해서 POST 요청 발생 시 서버가 변경될 수 있음))
    • POST는 리소스를 생성/변경하기 위해 설계되었기 때문에, HTTP 메세지의 Body에 담아 전송
    • POST 요청은 캐시되지 않고, 브라우저 히스토리에 남지 않으며, 데이터 길이에 제한이 없음
    • 메서드의 매개변수 이름과 템플릿의 항목 이름이 같아야 함
    • @GetMapping과 매개변수가 다른 경우 같은 메서드 이름을 사용할 수 있음(메서드 오버로딩)
    • 보안 등을 생각한다면 조회 빼고는 POST 처리하는 게 좋을 수도 있음
    • GET과 POST를 제외한 요청은 HTML에서 적용이 안 됨 -> hiddenmethod를 키면 실제는 POST지만 요청을 이식해서 자동 변환(PATCH : 수정, DELETE : 삭제)



📢 검증과 상태 코드

👉 @Valid


  • 매개변수 앞에 @Valid 어노테이션을 적용해야 Form 클래스에 어노테이션으로 설정한 검증 기능이 작동(바인딩)
  • BindingResult
    • 항상 @Valid 뒤에 위치해야 하며, 어노테이션으로 인해 검증이 수행된 결과를 의미하는 객체
@PreAuthorize("isAuthenticated()")
@PostMapping("/create/{id}")
public String creatAnswer(Model model, @PathVariable("id") Integer id, @Valid AnswerForm answerForm, BindingResult bindingResult, Principal principal) {
	// ...
}

👉 @NotEmpty


  • Null 또는 빈 문자열("")을 허용하지 않음
  • @NotEmpty(message = "내용은 필수항목입니다.")
    • message : 검증이 실패할 경우 화면에 표시할 오류 메세지

👉 @Email


  • 주어진 문자열이 유효한 이메일 주소 형식인지 검사하는 역할

👉 @Size


  • 문자열, 컬렉션, 배열 등이 특정 크기 조건을 만족하는지 검증하기 위해 사용
  • 필드, 메서드 파라미터, 메서드 반환 값 등에 적용될 수 있으며, 주로 JPA 엔터티 클래스나 DTO(Data Transfer Object), Form Object 등에서 사용
  • @Size(min = 3, max = 24)
    • 글자의 길이가 3바이트보다 작을 수 없고, 24바이트보다 클 수 없음

👉 @ResponseStatus


  • HTTP 상태 코드와 선택적으로 이유(Reason)를 정의할 수 있음
  • 특정 메서드나 예외 클래스에 붙여 사용하며, 해당 메서드가 호출되거나 예외가 발생했을 때 반환할 HTTP 상태 코드를 지정
  • @ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "entity not found")
    • DataNotFoundException이 발생하면 @ResponseStatus 어노테이션에 의해 404오류(HttpStatus.NOT_FOUND)가 나타날 것



📢 데이터베이스와 JPA

👉 @Column


  • 컬럼 명과 일치, 컬럼의 세부 설정을 위해 사용
  • Entity의 속성은 @Column을 사용하지 않아도 테이블 컬럼으로 인식
  • 인식하고 싶지 않다면 @Transient 사용
  • 카멜 표기법이 DB 컬럼으로 전환될 때는 createDate -> create_date로 전환
  • @Column(columnDefinition = "TEXT")
    • columnDefinition : 컬럼의 속성 정의

👉 @EntityListeners


  • 엔터티 클래스에 적용되며, 특정 엔터티 리스너 클래스를 연결하는 역할
  • 리스너 클래스는 엔터티의 생명주기 이벤트(예: 생성, 수정, 삭제 등)에 따라 특정 로직을 실행할 수 있음
  • @EntityListeners(AuditingEntityListener.class)
    • AuditingEntityListener를 이용해 생성일과 수정일 등을 자동으로 관리
    • 필드 레벨에는 @CreatedDate@LastModifiedDate 등의 어노테이션을 사용하여 어떤 필드가 자동으로 관리되어야 하는지 지정

👉 @GeneratedValue


  • 엔티티의 기본 키 필드가 어떻게 자동 생성되는지 지정
  • 이 어노테이션은 보통 @Id 어노테이션이 붙은 필드와 함께 사용되어, 해당 필드의 값이 어떤 전략을 통해 생성될 것인지를 명시
  • @GeneratedValue(strategy = GenerationType.IDENTITY)
    • strategy : 고유 번호 생성하는 옵션
      • GenerationType.IDENTITY : 해당 컬럼에 독립적인 시퀀스를 생성하여 번호를 증가시킬 때 사용 == Auto_increment

👉 @ManyToOne, @OneToMany


  • 관계 설정 : 엔티티에 서로 연결된 속성이라는 것을 명시해야 함
  • 관계 설정할 때 사용하는 어노테이션 : @ManyToMany(N:N관계) @ManyToOne(N:1관계) @OneToMany(1:N관계) 등
  • @OneToMany(mappedBy = "question", cascade = CascadeType.REMOVE)
    • mappedBy : 참조 엔티티의 속성명 -> Answer에서 Question이라고 선언했으니 question이라고 매핑
    • cascade : OneToMany, ManyToOne 일 때(parent-child 관계), 엔티티의 상태가 변화하면 관계가 있는 엔티티에도 상태 변화를 전파시키는 옵션
      • CascadeType.REMOVE : 질문 하나에 답변이 여러 개일 수 있는데, 질문을 삭제하면 답변들도 전부 삭제될 수 있게 작성한 속성(부모 엔티티가 삭제되면 자식 엔티티도 삭제되는 속성)

👉 @JoinColumn


  • 두 엔티티 간의 관계를 데이터베이스 테이블의 컬럼에 매핑하는 역할
  • 주로 @ManyToOne, @OneToOne, @OneToMany, @ManyToMany와 같은 엔터티 관계 매핑 어노테이션과 함께 사용
  • @JoinColumn은 외래 키(foreign key) 관계를 설정할 때 사용되며, 해당 엔터티가 소유하고 있는 (즉, 외래 키가 있는) 테이블의 컬럼을 지정
  • 이 어노테이션을 명시적으로 사용하는 것은 기본 동작(JPA의 기본 전략에 따라 FK 생성)을 덮어쓰거나, 추가적인 외래 키 제약 조건(예: nullable, unique 등)을 설정할 때 유용
@Entity
public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    // ... 다른 필드들
}

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

    @ManyToOne
    @JoinColumn(name = "customer_id")  // 외래 키 컬럼을 지정
    private Customer customer;

    // ... 다른 필드들
}


📢 스프링 컨테이너와 설정

👉 @Component


  • 스프링 컨테이너에 등록하여 해당 클래스의 인스턴스를 스프링에서 직접 관리할 수 있게 됨 → 개발자가 직접 작성한 클래스를 Bean으로 등록하는 어노테이션
  • 타임리프에서 @로 접근 가능
  • 다른 클래스에서 해당 클래스의 인스턴스를 생성하고 사용할 때에도 스프링의 의존성 주입 기능을 활용하여 쉽게 관리할 수 있음

👉 @Configuration


  • 스프링의 환경설정 파일임을 의미하는 어노테이션

👉 @EnableWebSecurity


  • Security 구성 클래스에서 다양한 보안 구성을 수행할 수 있으며, 인증 및 권한 부여 매커니즘을 사용하여 웹 애플리케이션 보안을 확보
  • 모든 요청 URL이 스프링 시큐리티의 제어를 받도록 만드는 어노테이션
  • 어노테이션을 사용하여 Security 활성화하고, 이를 통해 Security를 구성하는데 필요한 설정 클래스를 자동으로 등록
  • 해당 어노테이션을 사용하면 내부적으로 SpringSecurityFilterChain이 동작하여 URL 필터가 적용

👉 @Bean


  • 메서드에 이 어노테이션을 붙이면 해당 메서드가 반환하는 객체가 Spring IoC(Inversion of Control) 컨테이너에 등록됨
@Configuration
public class AppConfig {

  @Bean
  public MyService myService() {
    return new MyServiceImpl();
  }
}

👉 @ConfigurationProperties


  • application.properties나 application.yml과 같은 외부 설정 파일에 정의된 속성들을 자바 객체에 자동으로 바인딩해줌
  • 설정값들을 프로그램에서 쉽게 사용할 수 있게 됨
  • @ConfigurationProperties(prefix = "app.database")
    • 아래처럼 사용할 수 있음
      app:
        database:
          url: jdbc:mysql://localhost:3306/mydb
          username: root
          password: secret
      import org.springframework.boot.context.properties.ConfigurationProperties;
      import org.springframework.stereotype.Component;
      
      @Component
      @ConfigurationProperties(prefix = "app.database")
      public class DatabaseProperties {
          private String url;
          private String username;
          private String password;
      
          // Getter와 Setter 메서드
      }
      import org.springframework.beans.factory.annotation.Autowired;
      
      public class SomeService {
          
          @Autowired
          private DatabaseProperties databaseProperties;
      
          public void doSomething() {
              String url = databaseProperties.getUrl();
              String username = databaseProperties.getUsername();
              // ...
          }
      }


📢 트랜잭션 관리

👉 @Transactional


  • 메서드나 클래스에 적용하여 해당 부분이 트랜잭션의 범위에 포함되도록 지정
    • 트랜잭션(Transaction)은 데이터베이스에서 데이터를 안전하게 처리하기 위한 작업의 단위
  • 이 어노테이션을 사용하면 메서드의 실행이 하나의 트랜잭션으로 처리되며, 예외가 발생하면 자동으로 롤백됨
@Service
public class MyService {

  @Transactional
  public void doSomething() {
    // DB 작업
  }
}


📢 접근 제어

👉 @PreAuthorize


  • 메서드 호출 전에 검사
  • "isAuthenticated()" : 요청에 대해 인증된 사용자만 접근할 수 있도록 설정하는 메서드 -> 로그인한 상태
    • @PreAuthorize("isAuthenticated()")



📢 생성자와 빌더

👉 @NoArgsConstructor


  • 클래스에 기본 생성자를 자동으로 추가
    • “기본 생성자"라는 것은 모든 필드를 초기화하지 않는 생성자를 의미

👉 @AllArgsConstructor


  • 클래스에 모든 필드를 인자로 가지는 생성자를 추가

👉 @RequiredArgsConstructor


  • 초기화되지 않은 final 필드 또는 @NonNull로 어노테이트 필드에 대해 생성자를 생성
  • 즉, final 필드와 @NonNull로 표시된 필드 모두를 포함하는 생성자를 생성

👉 @Builder


  • 빌더 패턴을 적용한 클래스를 생성
  • 빌더 패턴은 객체 생성을 더 유연하고 코드 가독성을 높이는 패턴

👉 @SuperBuilder


  • 빌더 패턴을 구현한 클래스를 자동으로 생성
  • @Builder의 확장된 버전으로, 상속된 클래스 구조에서 Builder 패턴을 사용하고자 할 때 유용
    • @SuperBuilder를 사용할 때는 상속 구조 내에서 모든 관련 클래스에 @SuperBuilder를 적용해야 함
profile
공부 중인 신입 백엔드 개발자입니다

0개의 댓글