
Spring Boot는 다양한 애너테이션을 제공하여 개발자가 간결하고 효과적으로 애플리케이션을 구성하고 개발할 수 있도록 도와줍니다.
아래는 Spring Boot에서 자주 사용하는 애너테이션들과 그 설명입니다 :D
1. @SpringBootApplication
Spring Boot 애플리케이션의 진입점(entry point)에 사용되는 애너테이션입니다.
이 애너테이션은 @EnableAutoConfiguration, @ComponentScan, @Configuration을 포함합니다. (그래서 직접 사용할 필요 X)
@EnableAutoConfiguration 역할
Spring Boot 애플리케이션에서 자동 구성(autoconfiguration)을 활성화합니다. Spring Boot는 클래스패스에 있는 라이브러리와 설정 파일을 기반으로 다양한 빈(bean)을 자동으로 구성합니다.
@ComponentScan 역할
지정된 패키지와 하위 패키지를 스캔하여 @Component, @Service, @Repository, @Controller와 같은 애너테이션이 붙은 클래스를 찾아 Spring 빈으로 등록합니다.
@Configuration 역할
@Configuration 애너테이션이 붙은 클래스는 Spring IoC 컨테이너를 위한 빈 정의를 포함하는 설정 클래스임을 나타냅니다. 이 클래스 안에서는 @Bean 애너테이션을 사용하여 메서드가 반환하는 객체를 Spring 컨텍스트에 빈으로 등록할 수 있습니다.
• 예제:
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
2. @Configuration
Spring 설정 클래스를 정의할 때 사용됩니다. 이 클래스는 @Bean 애너테이션을 사용하여 Spring 빈을 정의할 수 있습니다.
고급 사용법 예시)
1) 프로파일 기반 설정
@Configuration 클래스는 특정 프로파일에서만 활성화되도록 설정할 수 있습니다
package com.example.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration
@Profile("development")
public class DevConfig {
// "development" 프로파일이 활성화된 경우에만 DevConfig 설정 클래스가 활성화됩니다.
@Bean
public DevService devService() {
return new DevServiceImpl();
}
}
2) @Import
다른 설정 클래스를 포함할 수 있습니다:
package com.example.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import({ AppConfig.class, DevConfig.class })
public class MainConfig {
}
3. @Bean
메서드 레벨에서 사용되며, 해당 메서드가 반환하는 객체를 Spring 컨텍스트에 빈으로 등록합니다.
• 예제:
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyService();
}
}
4. @Component
Spring 컨텍스트에 빈으로 등록할 클래스를 표시합니다. @Service, @Repository, @Controller와 같은 특수화된 애너테이션의 상위 애너테이션입니다.
• 예제:
@Component
public class MyComponent {
// ...
}
5. @Controller
웹 컨트롤러 클래스를 나타내며, 주로 HTTP 요청을 처리하고 응답을 반환하는 데 사용됩니다.
• 예제:
@Controller
public class MyController {
@GetMapping("/hello")
public String hello() {
return "hello";
}
}
6. @ResponseBody
메서드의 반환 값을 HTTP 응답 본문으로 변환하여 클라이언트로 보낼 때 사용됩니다.
@Controller
public class MyController {
@GetMapping("/hello")
@ResponseBody
public String hello() {
return "Hello, World!";
}
}
7. @RestController
@Controller와 @ResponseBody를 결합한 애너테이션입니다. JSON/XML 형식의 데이터를 반환하는 RESTful 웹 서비스를 개발할 때 사용됩니다.
• 예제:
@RestController
public class MyRestController {
@GetMapping("/api/hello")
public String hello() {
return "Hello, World!";
}
}
8. @RequestMapping
HTTP 요청 URL을 매핑하는 데 사용됩니다. 클래스나 메서드에 적용할 수 있으며,
@GetMapping, @PostMapping, @PutMapping, @DeleteMapping과 같은 특수화된 애너테이션이 있습니다.
• 예제:
@RestController
@RequestMapping("/api")
public class MyRestController {
@GetMapping("/hello")
public String hello() {
return "Hello, World!";
}
}
9. @RequestParam
HTTP 요청 파라미터의 값을 메서드 파라미터로 받을 때 사용됩니다.
• 예제:
@RestController
@RequestMapping("/api")
public class MyRestController {
@GetMapping("/hello")
public String hello(@RequestParam String name) {
return "Hello, " + name;
}
}
10. @PathVariable
URL 경로에 있는 값을 메서드 파라미터로 받을 때 사용됩니다.
• 예제:
@RestController
@RequestMapping("/api")
public class MyRestController {
@GetMapping("/hello/{name}")
public String hello(@PathVariable String name) {
return "Hello, " + name;
}
}
11. @RequestBody
HTTP 요청의 본문(body)을 메서드 파라미터로 받아오는 데 사용됩니다. 주로 JSON 데이터를 Java 객체로 변환할 때 사용됩니다.
• 예제:
@RestController
@RequestMapping("/api")
public class MyRestController {
@PostMapping("/hello")
public String createHello(@RequestBody HelloRequest helloRequest) {
return "Created: " + helloRequest.getMessage();
}
}
public class HelloRequest {
private String message;
// getters and setters
}
12. @Service
서비스 레이어 클래스를 나타내며, @Component와 동일하게 동작합니다.
• 예제:
@Service
public class MyService {
// ...
}
13. @Repository
데이터 액세스 객체(DAO) 클래스에 사용됩니다. 데이터베이스 예외를 Spring 데이터 예외로 변환하는 역할도 합니다.
• 예제:
@Repository
public class MyRepository {
// ...
}
14. @Autowired
Spring이 의존성을 자동으로 주입하도록 지시합니다. 생성자, 세터 메서드, 필드에 사용할 수 있습니다.
• 예제:
@Service
public class MyService {
private final MyRepository myRepository;
@Autowired
public MyService(MyRepository myRepository) {
this.myRepository = myRepository;
}
}
15. @RequiredArgsContructor
Lombok 라이브러리에서 제공하는 애너테이션으로, 클래스의 final 필드나 @NonNull 애너테이션이 붙은 필드에 대해 생성자를 자동으로 생성해줍니다. 이를 통해 의존성 주입을 편리하게 할 수 있습니다.
• 예제:
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class MyService {
private final MyRepository myRepository;
private final AnotherDependency anotherDependency;
// Lombok은 아래와 같은 생성자를 자동으로 생성합니다.
// MyService(MyRepository myRepository, AnotherDependency anotherDependency) {
// this.myRepository = myRepository;
// this.anotherDependency = anotherDependency;
// }
}
🧚🏻♀️ 잠깐! @Autowired와 @RequiredArgsConstructor 두 방식의 차이점과 장단점
• 생성자 주입: Spring에서 생성자 주입은 의존성 주입의 권장 방식입니다. @RequiredArgsConstructor를 사용하면 생성자 주입을 더 간결하게 작성할 수 있으며, 클래스의 불변성을 보장하고, 테스트하기도 더 용이합니다.
• Lombok 사용: Lombok을 사용하여 @RequiredArgsConstructor를 활용하면, 코드의 간결성을 유지하면서도 좋은 설계 원칙을 따를 수 있습니다.
따라서 -> Lombok을 사용하는 경우 @RequiredArgsConstructor를 사용하는 것이 더 나은 선택일 수 있습니다. 이로써 불변성, 테스트 용이성, 코드 간결성을 모두 확보할 수 있습니다. 그러나 Lombok을 사용하지 않거나 프로젝트의 규모가 작다면, @Autowired를 사용해도 큰 문제가 없을 것입니다. Spring에서는 생성자 주입을 권장하지만, 상황에 따라 적절한 방법을 선택하는 것이 중요합니다.
16. @Value
외부 설정 파일(application.properties 또는 application.yml)의 값을 주입할 때 사용됩니다.
• 예제:
@Component
public class MyComponent {
@Value("${my.property}")
private String myProperty;
// ...
}
17. @Transactional
메서드나 클래스에 트랜잭션을 적용합니다. 이 애너테이션이 붙은 메서드나 클래스는 트랜잭션 경계 내에서 실행됩니다.
• 예제:
@Service
public class MyService {
@Transactional
public void performTransaction() {
// 트랜잭션 내에서 실행되는 코드
}
}
18. @ControllerAdvice, @RestControllerAdvice
애플리케이션 전역에서 예외를 처리하거나, 특정 컨트롤러에서 공유되는 @ExceptionHandler, @InitBinder, @ModelAttribute 메서드를 정의합니다.
모든 @Controller에 대해 예외를 잡아 처리해주는 어노테이션으로
클래스 파일위에 @ControllerAdvice 어노테이션을 붙이면 돼서 간편하며,
클래스 안에는 @ExceptionHandler를 통해 내가 핸들링하고 싶은 예외를 잡아서 처리하면 됩니다.
-> 에러 페이지로 리다이렉트를 시키기를 원한다면 @ControllerAdvice를 사용
추가로 @RestControllerAdvice 어노테이션도 존재하는데 이는 Controller와 RestController의 차이와 비슷하게 @ResponseBody 어노테이션이 추가된 형태입니다.
-> API 서버를 운영하면서 객체만 리턴 시키려면 @RestControllerAdvice를 사용
19. @ExceptionHandler
특정 예외를 처리하는 메서드를 정의합니다.
• 예제:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(RuntimeException.class)
@ResponseBody
public String handleRuntimeException(RuntimeException ex) {
return "Error: " + ex.getMessage();
}
}
20. @EnableAsync
Spring 애플리케이션에서 비동기 실행 기능을 활성화합니다. 이를 통해 @Async 애너테이션이 붙은 메서드가 실제로 비동기적으로 실행될 수 있게 합니다. 이 애너테이션이 있어야 @Async가 제대로 동작합니다.
• 예제:
@Configuration
@EnableAsync
public class AsyncConfig {
// 추가적인 비동기 설정이 필요한 경우 여기서 설정
}
21. @Async
비동기 메서드를 정의합니다. 이 애너테이션이 붙은 메서드는 별도의 스레드에서 실행됩니다.
@Async 메서드는 void, Future, CompletableFuture와 같은 리턴 타입을 가질 수 있습니다.
• 예제:
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class MyService {
@Async
public void asyncMethod() {
// 비동기로 실행할 코드
System.out.println("Async method executing");
}
@Async
public Future<String> asyncMethodWithReturn() {
// 비동기로 실행할 코드
return new AsyncResult<>("Hello, World!");
}
@Async
public CompletableFuture<String> asyncMethodWithCompletableFuture() {
// 비동기로 실행할 코드
return CompletableFuture.completedFuture("Hello, World!");
}
}
22. @EnableScheduling
Spring의 스케줄링 기능을 활성화합니다. 이를 통해 @Scheduled 애너테이션이 붙은 메서드가 실제로 주기적으로 실행될 수 있습니다.
주로 설정 클래스에 사용되어 스케줄링 기능을 전역적으로 활성화합니다.
• 예제:
@Configuration
@EnableScheduling
public class SchedulingConfig {
// 추가적인 스케줄링 설정이 필요한 경우 여기서 설정
}
23. @Scheduled
특정 메서드를 일정 간격으로 실행하도록 예약합니다.
• 예제:
@Component
public class ScheduledTasks {
@Scheduled(fixedRate = 5000)
public void performTask() {
// 5초마다 실행되는 코드
}
}
'Framework > Spring' 카테고리의 다른 글
[Spring] Spring Security 기본 설정 방법 (Spring Boot 3, SecurityFilterChain) (0) | 2024.07.04 |
---|---|
[Spring] RESTful API 컨트롤러의 @GetMapping 에서 데이터를 받는 방법 (0) | 2024.07.03 |
[Spring Boot] application.yml이란? application.yml 설정 방법 (0) | 2024.06.29 |
[Spring Boot] application.properties와 application.yml 차이 (0) | 2024.06.29 |
[Spring] message.yml 이란? 사용 목적, 사용 예시 (0) | 2024.06.29 |

Spring Boot는 다양한 애너테이션을 제공하여 개발자가 간결하고 효과적으로 애플리케이션을 구성하고 개발할 수 있도록 도와줍니다.
아래는 Spring Boot에서 자주 사용하는 애너테이션들과 그 설명입니다 :D
1. @SpringBootApplication
Spring Boot 애플리케이션의 진입점(entry point)에 사용되는 애너테이션입니다.
이 애너테이션은 @EnableAutoConfiguration, @ComponentScan, @Configuration을 포함합니다. (그래서 직접 사용할 필요 X)
@EnableAutoConfiguration 역할
Spring Boot 애플리케이션에서 자동 구성(autoconfiguration)을 활성화합니다. Spring Boot는 클래스패스에 있는 라이브러리와 설정 파일을 기반으로 다양한 빈(bean)을 자동으로 구성합니다.
@ComponentScan 역할
지정된 패키지와 하위 패키지를 스캔하여 @Component, @Service, @Repository, @Controller와 같은 애너테이션이 붙은 클래스를 찾아 Spring 빈으로 등록합니다.
@Configuration 역할
@Configuration 애너테이션이 붙은 클래스는 Spring IoC 컨테이너를 위한 빈 정의를 포함하는 설정 클래스임을 나타냅니다. 이 클래스 안에서는 @Bean 애너테이션을 사용하여 메서드가 반환하는 객체를 Spring 컨텍스트에 빈으로 등록할 수 있습니다.
• 예제:
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
2. @Configuration
Spring 설정 클래스를 정의할 때 사용됩니다. 이 클래스는 @Bean 애너테이션을 사용하여 Spring 빈을 정의할 수 있습니다.
고급 사용법 예시)
1) 프로파일 기반 설정
@Configuration 클래스는 특정 프로파일에서만 활성화되도록 설정할 수 있습니다
package com.example.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration
@Profile("development")
public class DevConfig {
// "development" 프로파일이 활성화된 경우에만 DevConfig 설정 클래스가 활성화됩니다.
@Bean
public DevService devService() {
return new DevServiceImpl();
}
}
2) @Import
다른 설정 클래스를 포함할 수 있습니다:
package com.example.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import({ AppConfig.class, DevConfig.class })
public class MainConfig {
}
3. @Bean
메서드 레벨에서 사용되며, 해당 메서드가 반환하는 객체를 Spring 컨텍스트에 빈으로 등록합니다.
• 예제:
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyService();
}
}
4. @Component
Spring 컨텍스트에 빈으로 등록할 클래스를 표시합니다. @Service, @Repository, @Controller와 같은 특수화된 애너테이션의 상위 애너테이션입니다.
• 예제:
@Component
public class MyComponent {
// ...
}
5. @Controller
웹 컨트롤러 클래스를 나타내며, 주로 HTTP 요청을 처리하고 응답을 반환하는 데 사용됩니다.
• 예제:
@Controller
public class MyController {
@GetMapping("/hello")
public String hello() {
return "hello";
}
}
6. @ResponseBody
메서드의 반환 값을 HTTP 응답 본문으로 변환하여 클라이언트로 보낼 때 사용됩니다.
@Controller
public class MyController {
@GetMapping("/hello")
@ResponseBody
public String hello() {
return "Hello, World!";
}
}
7. @RestController
@Controller와 @ResponseBody를 결합한 애너테이션입니다. JSON/XML 형식의 데이터를 반환하는 RESTful 웹 서비스를 개발할 때 사용됩니다.
• 예제:
@RestController
public class MyRestController {
@GetMapping("/api/hello")
public String hello() {
return "Hello, World!";
}
}
8. @RequestMapping
HTTP 요청 URL을 매핑하는 데 사용됩니다. 클래스나 메서드에 적용할 수 있으며,
@GetMapping, @PostMapping, @PutMapping, @DeleteMapping과 같은 특수화된 애너테이션이 있습니다.
• 예제:
@RestController
@RequestMapping("/api")
public class MyRestController {
@GetMapping("/hello")
public String hello() {
return "Hello, World!";
}
}
9. @RequestParam
HTTP 요청 파라미터의 값을 메서드 파라미터로 받을 때 사용됩니다.
• 예제:
@RestController
@RequestMapping("/api")
public class MyRestController {
@GetMapping("/hello")
public String hello(@RequestParam String name) {
return "Hello, " + name;
}
}
10. @PathVariable
URL 경로에 있는 값을 메서드 파라미터로 받을 때 사용됩니다.
• 예제:
@RestController
@RequestMapping("/api")
public class MyRestController {
@GetMapping("/hello/{name}")
public String hello(@PathVariable String name) {
return "Hello, " + name;
}
}
11. @RequestBody
HTTP 요청의 본문(body)을 메서드 파라미터로 받아오는 데 사용됩니다. 주로 JSON 데이터를 Java 객체로 변환할 때 사용됩니다.
• 예제:
@RestController
@RequestMapping("/api")
public class MyRestController {
@PostMapping("/hello")
public String createHello(@RequestBody HelloRequest helloRequest) {
return "Created: " + helloRequest.getMessage();
}
}
public class HelloRequest {
private String message;
// getters and setters
}
12. @Service
서비스 레이어 클래스를 나타내며, @Component와 동일하게 동작합니다.
• 예제:
@Service
public class MyService {
// ...
}
13. @Repository
데이터 액세스 객체(DAO) 클래스에 사용됩니다. 데이터베이스 예외를 Spring 데이터 예외로 변환하는 역할도 합니다.
• 예제:
@Repository
public class MyRepository {
// ...
}
14. @Autowired
Spring이 의존성을 자동으로 주입하도록 지시합니다. 생성자, 세터 메서드, 필드에 사용할 수 있습니다.
• 예제:
@Service
public class MyService {
private final MyRepository myRepository;
@Autowired
public MyService(MyRepository myRepository) {
this.myRepository = myRepository;
}
}
15. @RequiredArgsContructor
Lombok 라이브러리에서 제공하는 애너테이션으로, 클래스의 final 필드나 @NonNull 애너테이션이 붙은 필드에 대해 생성자를 자동으로 생성해줍니다. 이를 통해 의존성 주입을 편리하게 할 수 있습니다.
• 예제:
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class MyService {
private final MyRepository myRepository;
private final AnotherDependency anotherDependency;
// Lombok은 아래와 같은 생성자를 자동으로 생성합니다.
// MyService(MyRepository myRepository, AnotherDependency anotherDependency) {
// this.myRepository = myRepository;
// this.anotherDependency = anotherDependency;
// }
}
🧚🏻♀️ 잠깐! @Autowired와 @RequiredArgsConstructor 두 방식의 차이점과 장단점
• 생성자 주입: Spring에서 생성자 주입은 의존성 주입의 권장 방식입니다. @RequiredArgsConstructor를 사용하면 생성자 주입을 더 간결하게 작성할 수 있으며, 클래스의 불변성을 보장하고, 테스트하기도 더 용이합니다.
• Lombok 사용: Lombok을 사용하여 @RequiredArgsConstructor를 활용하면, 코드의 간결성을 유지하면서도 좋은 설계 원칙을 따를 수 있습니다.
따라서 -> Lombok을 사용하는 경우 @RequiredArgsConstructor를 사용하는 것이 더 나은 선택일 수 있습니다. 이로써 불변성, 테스트 용이성, 코드 간결성을 모두 확보할 수 있습니다. 그러나 Lombok을 사용하지 않거나 프로젝트의 규모가 작다면, @Autowired를 사용해도 큰 문제가 없을 것입니다. Spring에서는 생성자 주입을 권장하지만, 상황에 따라 적절한 방법을 선택하는 것이 중요합니다.
16. @Value
외부 설정 파일(application.properties 또는 application.yml)의 값을 주입할 때 사용됩니다.
• 예제:
@Component
public class MyComponent {
@Value("${my.property}")
private String myProperty;
// ...
}
17. @Transactional
메서드나 클래스에 트랜잭션을 적용합니다. 이 애너테이션이 붙은 메서드나 클래스는 트랜잭션 경계 내에서 실행됩니다.
• 예제:
@Service
public class MyService {
@Transactional
public void performTransaction() {
// 트랜잭션 내에서 실행되는 코드
}
}
18. @ControllerAdvice, @RestControllerAdvice
애플리케이션 전역에서 예외를 처리하거나, 특정 컨트롤러에서 공유되는 @ExceptionHandler, @InitBinder, @ModelAttribute 메서드를 정의합니다.
모든 @Controller에 대해 예외를 잡아 처리해주는 어노테이션으로
클래스 파일위에 @ControllerAdvice 어노테이션을 붙이면 돼서 간편하며,
클래스 안에는 @ExceptionHandler를 통해 내가 핸들링하고 싶은 예외를 잡아서 처리하면 됩니다.
-> 에러 페이지로 리다이렉트를 시키기를 원한다면 @ControllerAdvice를 사용
추가로 @RestControllerAdvice 어노테이션도 존재하는데 이는 Controller와 RestController의 차이와 비슷하게 @ResponseBody 어노테이션이 추가된 형태입니다.
-> API 서버를 운영하면서 객체만 리턴 시키려면 @RestControllerAdvice를 사용
19. @ExceptionHandler
특정 예외를 처리하는 메서드를 정의합니다.
• 예제:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(RuntimeException.class)
@ResponseBody
public String handleRuntimeException(RuntimeException ex) {
return "Error: " + ex.getMessage();
}
}
20. @EnableAsync
Spring 애플리케이션에서 비동기 실행 기능을 활성화합니다. 이를 통해 @Async 애너테이션이 붙은 메서드가 실제로 비동기적으로 실행될 수 있게 합니다. 이 애너테이션이 있어야 @Async가 제대로 동작합니다.
• 예제:
@Configuration
@EnableAsync
public class AsyncConfig {
// 추가적인 비동기 설정이 필요한 경우 여기서 설정
}
21. @Async
비동기 메서드를 정의합니다. 이 애너테이션이 붙은 메서드는 별도의 스레드에서 실행됩니다.
@Async 메서드는 void, Future, CompletableFuture와 같은 리턴 타입을 가질 수 있습니다.
• 예제:
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class MyService {
@Async
public void asyncMethod() {
// 비동기로 실행할 코드
System.out.println("Async method executing");
}
@Async
public Future<String> asyncMethodWithReturn() {
// 비동기로 실행할 코드
return new AsyncResult<>("Hello, World!");
}
@Async
public CompletableFuture<String> asyncMethodWithCompletableFuture() {
// 비동기로 실행할 코드
return CompletableFuture.completedFuture("Hello, World!");
}
}
22. @EnableScheduling
Spring의 스케줄링 기능을 활성화합니다. 이를 통해 @Scheduled 애너테이션이 붙은 메서드가 실제로 주기적으로 실행될 수 있습니다.
주로 설정 클래스에 사용되어 스케줄링 기능을 전역적으로 활성화합니다.
• 예제:
@Configuration
@EnableScheduling
public class SchedulingConfig {
// 추가적인 스케줄링 설정이 필요한 경우 여기서 설정
}
23. @Scheduled
특정 메서드를 일정 간격으로 실행하도록 예약합니다.
• 예제:
@Component
public class ScheduledTasks {
@Scheduled(fixedRate = 5000)
public void performTask() {
// 5초마다 실행되는 코드
}
}
'Framework > Spring' 카테고리의 다른 글
[Spring] Spring Security 기본 설정 방법 (Spring Boot 3, SecurityFilterChain) (0) | 2024.07.04 |
---|---|
[Spring] RESTful API 컨트롤러의 @GetMapping 에서 데이터를 받는 방법 (0) | 2024.07.03 |
[Spring Boot] application.yml이란? application.yml 설정 방법 (0) | 2024.06.29 |
[Spring Boot] application.properties와 application.yml 차이 (0) | 2024.06.29 |
[Spring] message.yml 이란? 사용 목적, 사용 예시 (0) | 2024.06.29 |