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();
}
}
'Programming > Spring' 카테고리의 다른 글
| [JPA] 상속관계 매핑하기 (0) | 2024.02.09 |
|---|---|
| [Spring Boot] MessageSource - 오류 메시지 처리 방식 (0) | 2024.01.20 |
| [Spring Boot] Embeded Mode로 테스트 하기 (feat. H2 Database) (0) | 2024.01.16 |
| [Spring Boot] Bean Validation - 검증 기능 사용 방법 (0) | 2024.01.05 |
| Session에 대해서 - 컨트롤러에서 HttpSession 사용하기 (0) | 2023.12.21 |
Contents
Liked this Posting!