새소식

Programming/Spring

Spring Annotation 정리

 

 

스프링에서는 편의를 위해 제공하는 다양한 애너테이션이 있는데, 그중에서 자주 사용되는 애너테이션을 정리해보고자 한다.

각 애너테이션이 하는 역할을 간단하게 설명할 것이며 지속적으로 업데이트할 예정이다.

스프링 기본 애너테이션뿐만 아니라 자주 사용되는 라이브러리의 애너테이션도 포함한다.

 

 

Spring MVC

 

`@Controller`

  • 클래스에 적용하면 해당 클래스가 컨트롤러로 사용됨
  • 사용자의 요청을 처리하고 Model을 만들어 View에 전달하는 역할을 수행함
@Controller
public class MyController {

    @GetMapping("/hello")
    public String helloWorld() {
        return "hello"; //hello.html
    }
}

 

 

`@RestController`

  • 클래스에 적용하면 해당 클래스가 컨트롤러로 사용되며, JSON이나 문자 등 View가 아닌 데이터 자체를 반환
@RestController
public class MyController {

    @GetMapping("/hello")
    public String helloWorld() {
        return "Hello, World!"; //문자 자체를 반환함
    }
}

 

 

`@Service`

  • 비즈니스 로직이나 트랜잭션 관리와 같은 서비스 계층의 클래스에 적용
  • 해당 클래스가 Spring의 컨테이너 빈에 등록되어 스프링에서 관리됨
@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public User getUserById(Long id) {
        return userRepository.findById(id);
    }

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

 

 

`@Repository`

  • 데이터 접근을 담당하는 Bean을 표시하기 위한 애너테이션으로 DB와의 상호작용을 담당하는 클래스에 사용함
  • 다른 컴포넌트에서 해당 Repository를 주입받아 사용할 수 있음
  • 컴포넌트 스캔 및 예외 변환 AOP의 적용 대상이 됨
@Repository
public class UserRepository {

    public User getUserById(Long userId) {
        // 데이터베이스에서 사용자 정보를 조회하는 코드
        return user;
    }
}

 

 

`@RequestMapping`

  • 메서드 또는 클래스에 적용하여 요청 URL을 매핑할 수 있음
  • 클래스에 적용한 경우 클래스 내 모든 메서드의 기본 URL 지정 가능
@Controller
@RequestMapping("/exurl")
public class MyController {
    
    @RequestMapping(value = "/users", method = RequestMethod.GET) //path: /exurl/users
    public String myHandler() {
        //logic
        return "viewName";
    }
}

 

 

`@GetMapping`

  • GET 요청을 처리하는 메서드 지정
  • 특정 URL에 GET 요청이 들어왔을 때 해당 메서드가 실행됨
@RestController
public class HelloController {

    @GetMapping("/hello")
    public String helloWorld() {
        return "Hello, World!";
    }
}

 

 

`@PostMapping`

  • POST 요청을 처리하는 메서드 지정
  • 특정 URL에 POST 요청이 들어왔을 때 해당 메서드가 실행됨
@RestController
public class UserController {

    @PostMapping("/user")
    public String createUser() {
        // 사용자 생성 로직
        return "User created successfully!";
    }
}

 

 

`@Autowired`

  • 의존성 주입 기능
  • Spring이 해당 애너테이션이 있는 필드나 생성자, 메서드를 스캔하여 해당 클래스의 빈을 찾아 주입함
@Service
public class UserService {

    private UserRepository userRepository;

    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

}

 

 

`@RequestParam`

  • 메서드의 파라미터에 사용하여 요청 파라미터를 바인딩함
  • 파라미터명과 동일한 경우 value 생략 가능
@RequestMapping("/example")
public String myHandler(@RequestParam("paramName") String paramValue) {
    // handler logic
    return "viewName";
}

 

 

`@PathVariable`

  • URL에서 변수를 추출하여 메서드의 파라미터로 전달할 때 사용함
@RequestMapping("/example/{id}")
public String myHandler(@PathVariable("id") Long itemId) {
    // handler logic
    return "viewName";
}

 

 

`@ModelAttribute`

  • HTTP 요청 파라미터를 메서드 파라미터에 바인딩할 때 사용
  • `Model`에 자동으로 추가되어 View에 데이터를 전달할 수 있음
  • 파라미터명과 동일한 경우 value 생략 가능
@Controller
public class UserController {

    @PostMapping("/user")
    public String submitUserForm(@ModelAttribute User user) {
        //user 객체를 처리
        return "userResult";
    }
}

 

 

 

`@ResponseBody`

  • 메서드에 적용하여 메서드의 반환 값이 View 이름이 아니라 응답의 본문(body)으로 직접 전송함
  • `@RestController`를 사용하면 컨트롤러 내 모든 메서드에 `@ResponseBody`가 적용되는 것과 같음
@ResponseBody
@RequestMapping("/example")
public String myHandler() {
    String name = "hello";
    return name;
}

 

 

`@RequestBody`

  • HTTP 요청의 본문(body)을 메서드의 파라미터로 매핑함
  • JSON 등의 데이터를 객체로 변환하여 컨트롤러의 메서드에서 사용할 수 있음
@RestController
@RequestMapping("/api/users")
public class UserController {

    @PostMapping("/create")
    public ResponseEntity<String> createUser(@RequestBody User user) {
        // 받아온 User 객체를 이용하여 사용자 생성 로직 수행
        // 이하 코드 생략
    }
}
//클라이언트가 다음의 JSON을 본문에 담아 전송

{
  "username": "john_doe",
  "email": "john@example.com"
}


//JSON을 User 객체로 변환하고 createUser()의 파라미터로 전달하는 과정이 @RequestBody를 통해 이루어짐
//객체 클래스에 기본 생성자, getter와 setter가 있어야 함

public class User {
    private String username;
    private String email;

    // getter, setter 및 기타 메서드
}

 

 

 

Test

 

`@SpringBootTest`

  • 테스트 시 스프링 부트를 통해 스프링 컨테이너를 생성함
  • `@Autowired` 등을 통해 스프링 컨테이너가 관리하는 빈들을 사용할 수 있음
@SpringBootTest
class MemberServiceTest {
	...
}

 

 

`@TestConfiguration`

  • 테스트 클래스 내에서 내부 설정 클래스를 만드는 경우 추가적으로 필요한 스프링 빈들을 등록할 수 있음
@SpringBootTest
class MemberServiceTest {

    @TestConfiguration
    static class TestConfig {
        @Bean
        DataSource dataSource() {
            return new DriverManagerDataSource(URL, USERNAME, PASSWORD);
        }
        @Bean
        PlatformTransactionManager transactionManager() {
            return new DataSourceTransactionManager(dataSource());
        }
    }
    
    // 테스트 코드 작성
    ...
}

 

 

`@BeforeEach`

  • 테스트 실행 전 호출됨
@BeforeEach
void beforeEach() {
    // 실행할 코드 작성
}

 

 

`@AfterEach`

  • 실행한 테스트가 끝나는 시점에 호출됨
@AfterEach
void afterEach() {
    // 실행할 코드 작성
}

 

 

 

Lombok

 

  • Spring Boot에서 `Lombok`을 사용할 경우 다음과 같은 설정이 필요함
dependencies {
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    
    // 테스트 클래스에서 사용하기 위한 설정
    testCompileOnly 'org.projectlombok:lombok'
    testAnnotationProcessor 'org.projectlombok:lombok'
}

 

 

`@Getter`

  • 필드에 대한 getter를 자동으로 생성
@Getter
public class Example {
    private String name;
    
    //public String getName() {return name;}이 자동으로 생성됨
}

 

 

`@Setter`

  • 필드에 대한 setter를 자동으로 생성
@Setter
public class Example {
    private String name;
    
    //public void setName() {this.name = name;}이 자동으로 생성됨
}

 

 

`@NoArgsConstructor`

  • 기본 생성자를 자동으로 생성
@NoArgsConstructor
public class Example {
    private String name;
    private int age;
    
    //public Example() {}이 자동으로 생성됨
}

 

 

`@AllArgsConstructor`

  • 클래스의 모든 필드를 매개변수로 받는 생성자를 자동으로 생성
@AllArgsConstructor
public class Example {
    
    private String name;
    private int age;
    
    /*
        모든 필드를 파라미터로 받는 생성자가 자동으로 생성됨
        public Example(String name, int age) {
            this.name = name;
            this.age = age;
        }
    */
}

 

 

`@RequiredArgsConstructor`

  • 주요 필드에 대한 생성자를 자동으로 생성
  • 주요 필드: 필드가 final로 선언되거나 `@NonNull`이 붙은 경우에 해당됨
@RequiredArgsConstructor
public class Car {
    
    private String name;
    private final String model;
    private final int year;

    /*
        model, year 필드에 대한 생성자가 자동으로 생성됨
        public Car(String model, int year) {
            this.model = model;
            this.year = year;
        }
    */
}

 

 

`@ToString`

  • 해당 클래스에 대한 `toString()` 메서드를 자동으로 생성
  • `toString()` : 클래스의 각 필드에 대한 문자열 표현이 포함된 메서드
@ToString
public class Example {
    private String name;
    private int age;

    /*
        toString() 메서드가 자동으로 생성됨
        public String toString() {
            return "Example(name=" + this.name + ", age=" + this.age + ")";
        }
    */
}

 

 

`@Data`

  • `@ToString`, `@EqualsAndHashCode`, `@Getter`, `@Setter`, `@RequiredArgsConstructor`를 한번에 적용함

 

 

`@Slf4j`

  • SLF4J : Simple Logging Facade for Java의 약자로, 다양한 로깅 프레임워크의 인터페이스 라이브러리
  • SLF4J의 `Logger`를 생성해줌
  • 스프링에서는 의존성 추가가 필요하며, 스프링 부트에서는 기본적으로 등록되어 있음
@Slf4j
public class Slf4jEx {
    // 기타 코드 생략    
    log.error("DB error", e);
    log.info("class = {}", repository.getClass());
}

 

 

 

DB

 

`@Transactional`

  • 트랜잭션 처리가 필요한 곳에 사용
  • 클래스 또는 메서드에 적용 가능
  • 스프링의 Transaction AOP가 해당 애너테이션을 인식하여 Transaction Proxy를 적용함
  • 로직이 성공적으로 수행되면 commit, 실패하면 rollback됨
  • 테스트 클래스에서 사용 시 로직이 성공적으로 수행되어도 rollback됨

 

 

`@Commit`

  • 트랜잭션 처리되는 데이터가 강제 커밋되도록 함
  • 클래스 또는 메서드에 적용 가능
  • `@Rollback(value = false)`와 같음
@Commit
@Transactional
@Test
void saveItem() {
    // 수행할 코드 작성
}

 

 

`@Rollback`

  • 트랜잭션 처리되는 데이터가 강제 롤백되도록 함
  • 클래스 또는 메서드에 적용 가능
  • `@Rollback(value)`의 value 값(true 또는 false)에 따라 강제 롤백 또는 커밋 설정 가능
@Rollback(value = false)
@Transactional
@Test
void saveItem() {
    //logic
}

 

 

ETC

 

`@Configuration`

  • 애플리케이션 설정 정의 클래스에 사용
    • Bean 정의: 클래스 내부에서 `@Bean`으로 스프링 빈 정의 가능
    • Bean 스캐닝 설정: 클래스 내부에서 `@ComponentScan`으로 패키지를 스캔하고 컴포넌트를 빈으로 등록 가능
    • 다른 설정 클래스와 조합: `@Import`로 다른 설정 클래스를 가져와 현재 설정 클래스와 조합 가능
@Configuration
public class AppConfig {

    @Bean
    public UserService userService() { //수동으로 빈 등록
        return new UserService();
    }

    @Bean
    public UserRepository userRepository() {
        return new UserRepository();
    }
}

 

 

`@Component`

  • Spring에서 관리되는 빈을 정의할 때 사용
  • 해당 클래스를 스프링의 빈으로 등록
  • `@Repository`, `@Service`, `@Controller`는 모두 `@Component`에서 확장됨
@Component
public class MyService {
    //logic
}

 

 

`@ComponentScan`

  • Spring이 컴포넌트를 검색할 때 참조하는 패키지 지정
  • 특정 패키지와 하위 패키지에서 `@Component` 및 하위 애너테이션을 검색하여 스프링 빈으로 등록
//패키지 경로: com.example

@Configuration
@ComponentScan("com.example.services")
public class AppConfig {
    //Spring의 구성 클래스
}

 

 

`@PostConstruct`

  • 초기화 메서드를 지정할 수 있음
  • 스프링 빈의 초기화 작업을 수행할 때 사용
  • Bean이 생성된 후에 호출됨
@PostConstruct
public void initialize() {
    //빈이 생성된 후 초기화 작업 수행
}

 

 

`@EventListener`

  • 복잡한 도메인 의존성을 줄이기 위한 방법 중 하나
  • 특정 이벤트가 발생했을 때 실행되도록 함
@RequiredArgsConstructor
public class TestDataInit {
    private final ItemRepository itemRepository;

    //스프링 컨테이너가 완전히 초기화를 다 끝내고 실행 준비가 되었을 때 발생하는 이벤트
    @EventListener(ApplicationReadyEvent.class)
    public void initData() {
        //실행할 코드
    } 
}

 

 

`@Profile`

  • 프로파일을 기반으로 Bean의 조건부 등록/활성화에 사용
  • `@Profile`로 빈을 정의하면 해당 빈은 해당 프로파일이 활성화되어 있는 경우에만 스프링 컨테이너에 등록됨
  • profile은 'spring.profiles.active' 프로퍼티로 설정 가능
  • 다양한 용도로 사용 가능 ex) 개발 환경과 테스트 환경을 분리할 때
@Configuration
public class AppConfig {

    @Bean
    @Profile("development") //development 프로파일이 활성화되어 있을 때만 등록
    public DataSource dataSourceForDevelopment() {
        return new DevelopmentDataSource();
    }

    @Bean
    @Profile("production") //production 프로파일이 활성화되어 있을 때만 등록
    public DataSource dataSourceForProduction() {
        return new ProductionDataSource();
    }
}

 

 

 

 

Contents

Copied URL!

Liked this Posting!