안녕하세요! Devloo입니다 🙂 이번 시간에는 Spring Boot에서 많이 사용하는 어노테이션들을 살펴보려고 합니다.
Spring Boot 어노테이션은 Spring 애플리케이션에 대한 정보를 제공하는 메타데이터로, 애플리케이션 설정을 간편하게 해줍니다.
Spring Boot는 모든 기능을 포괄하는 프레임워크로, 설정과 설치의 번거로움을 최소화하여 개발자가 로직에 집중할 수 있도록 도와줍니다. 이러한 특징 덕분에 개발자들 사이에서 빠르게 인기를 얻고 있습니다.
또한, Spring Boot는 마이크로서비스 기반의 프레임워크로, 최소한의 시간과 노력으로 프로덕션 준비가 된 애플리케이션을 만들 수 있게 해줍니다.
Spring Boot의 주요 기능은 다음과 같습니다:
- Spring에서 흔히 볼 수 있는 복잡한 XML 설정을 피할 수 있습니다.
- REST 엔드포인트의 유지보수와 생성을 쉽게 할 수 있는 기능을 제공합니다.
- 내장된 Tomcat 서버를 포함하고 있습니다.
- WAR 및 JAR 파일을 Tomcat 서버에 쉽게 배포할 수 있어 배포가 매우 간편합니다.
Spring Boot 어노테이션은 주로 org.springframework.boot.autoconfigure
와 org.springframework.boot.autoconfigure.condition
패키지에 있으며, Spring Boot를 사용할 때 필수적입니다.
주요 Spring Boot 어노테이션 및 사용 예제
1. @SpringBootApplication
이 어노테이션은 Spring Boot 애플리케이션을 시작하는 데 사용됩니다. @Configuration
, @EnableAutoConfiguration
, @ComponentScan
의 세 가지 어노테이션을 결합합니다.
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
2. @RestController
이 어노테이션은 해당 클래스가 RESTful 컨트롤러임을 나타내며, @Controller
와 @ResponseBody
를 결합한 것입니다.
예시:
@RestController
public class MyController {
@GetMapping("/hello")
public String hello() {
return "Hello, World!";
}
}
Spring 4에서 도입된 이 어노테이션은 컨트롤러 클래스의 각 요청 처리 메서드에 @ResponseBody
를 사용하지 않아도 되도록 해줍니다.
한번 비교해 보겠습니다:
@Controller
@RequestMapping("/api/v1")
public class EmployeeController {
@Autowired
private EmployeeRepository employeeRepository;
@GetMapping("/employees")
public @ResponseBody List<Employee> getAllEmployees() {
return employeeRepository.findAll();
}
@GetMapping("/employees/{id}")
public @ResponseBody ResponseEntity<Employee> getEmployeeById(@PathVariable(value = "id") Long employeeId)
throws ResourceNotFoundException {
Employee employee = employeeRepository.findById(employeeId)
.orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId));
return ResponseEntity.ok().body(employee);
}
@PostMapping("/employees")
public @ResponseBody Employee createEmployee(@Valid @RequestBody Employee employee) {
return employeeRepository.save(employee);
}
@PutMapping("/employees/{id}")
public @ResponseBody ResponseEntity<Employee> updateEmployee(@PathVariable(value = "id") Long employeeId,
@Valid @RequestBody Employee employeeDetails) throws ResourceNotFoundException {
Employee employee = employeeRepository.findById(employeeId)
.orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId));
employee.setEmailId(employeeDetails.getEmailId());
employee.setLastName(employeeDetails.getLastName());
employee.setFirstName(employeeDetails.getFirstName());
final Employee updatedEmployee = employeeRepository.save(employee);
return ResponseEntity.ok(updatedEmployee);
}
@DeleteMapping("/employees/{id}")
public @ResponseBody Map<String, Boolean> deleteEmployee(@PathVariable(value = "id") Long employeeId)
throws ResourceNotFoundException {
Employee employee = employeeRepository.findById(employeeId)
.orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId));
employeeRepository.delete(employee);
Map<String, Boolean> response = new HashMap<>();
response.put("deleted", Boolean.TRUE);
return response;
}
}
이 예제에서는 각 반환 값이 @ResponseBody
로 어노테이션되어 있습니다.
위 예제에서 @RestController
를 사용하려면 @Controller
를 @RestController
로 교체하고 각 메서드의 @ResponseBody
를 제거하면 됩니다. 수정된 클래스는 다음과 같습니다:
@RestController
@RequestMapping("/api/v1")
public class EmployeeController {
@Autowired
private EmployeeRepository employeeRepository;
@GetMapping("/employees")
public List<Employee> getAllEmployees() {
return employeeRepository.findAll();
}
@GetMapping("/employees/{id}")
public ResponseEntity<Employee> getEmployeeById(@PathVariable(value = "id") Long employeeId)
throws ResourceNotFoundException {
Employee employee = employeeRepository.findById(employeeId)
.orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId));
return ResponseEntity.ok().body(employee);
}
@PostMapping("/employees")
public Employee createEmployee(@Valid @RequestBody Employee employee) {
return employeeRepository.save(employee);
}
@PutMapping("/employees/{id}")
public ResponseEntity<Employee> updateEmployee(@PathVariable(value = "id") Long employeeId,
@Valid @RequestBody Employee employeeDetails) throws ResourceNotFoundException {
Employee employee = employeeRepository.findById(employeeId)
.orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId));
employee.setEmailId(employeeDetails.getEmailId());
employee.setLastName(employeeDetails.getLastName());
employee.setFirstName(employeeDetails.getFirstName());
final Employee updatedEmployee = employeeRepository.save(employee);
return ResponseEntity.ok(updatedEmployee);
}
@DeleteMapping("/employees/{id}")
public Map<String, Boolean> deleteEmployee(@PathVariable(value = "id") Long employeeId)
throws ResourceNotFoundException {
Employee employee = employeeRepository.findById(employeeId)
.orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId));
employeeRepository.delete(employee);
Map<String, Boolean> response = new HashMap<>();
response.put("deleted", Boolean.TRUE);
return response;
}
}
이 어노테이션을 사용하면 코드의 가독성이 크게 향상됩니다.
3. @RequestMapping
@RequestMapping
어노테이션은 웹 요청을 특정 핸들러 메서드에 매핑할 때 사용됩니다. 클래스 또는 메서드 수준에서 적용할 수 있습니다.
예시:
@RestController
@RequestMapping("/api")
public class MyController {
@GetMapping("/hello")
public String hello() {
return "Hello, World!";
}
}
4. @Autowired
@Autowired
어노테이션은 Spring 빈에서 자동으로 의존성을 주입할 때 사용됩니다. 필드, 생성자 또는 메서드에 적용할 수 있습니다.
간단히 말해서, 이 어노테이션은 두 가지 기능을 합니다:
- 빈을 자동으로 주입합니다.
- 생성자 주입, 세터 주입, 필드 주입에 사용됩니다.
예시:
@Service
public class MyService {
private final MyRepository repository;
@Autowired
public MyService(MyRepository repository) {
this.repository = repository;
}
}
또 다른 예시:
@Autowired
private EmployeeRepository employeeRepository;
5. @Component
@Component
어노테이션은 Spring 프레임워크에서 클래스가 Spring이 관리하는 컴포넌트임을 나타냅니다.
Spring은 이 어노테이션을 통해 해당 클래스를 자동으로 스캔하고 인스턴스화하여 애플리케이션에서 의존성 주입을 통해 사용할 수 있게 합니다.
일반적으로 비즈니스 로직 계층, 데이터 접근 계층, 컨트롤러 등을 나타내며, Spring이 이들의 생명 주기를 관리하고 의존성을 주입할 수 있게 합니다.
예시:
@Component
public class MyComponent {
// ...
}
6. @Service
@Service
어노테이션은 클래스가 비즈니스 로직을 처리하는 서비스 계층의 Spring 빈임을 나타냅니다.
예시:
@Service
public class MyService {
// ...
}
7. @Repository
@Repository
어노테이션은 클래스가 데이터베이스 접근을 처리하는 특별한 유형의 Spring 빈임을 나타냅니다.
예시:
import org.springframework.stereotype.Repository;
@Repository
public class UserRepository {
public void saveUser(User user) {
// 사용자 정보를 데이터베이스에 저장하는 로직 구현
}
public User getUserById(Long id) {
// ID로 사용자 정보를 데이터베이스에서 조회하는 로직 구현
return null;
}
// 기타 데이터 접근 메서드...
}
이 예시에서 UserRepository
클래스는 @Repository
로 어노테이션되어 있으며, 이는 해당 클래스가 사용자 데이터와 관련된 영속성 작업을 수행하는 데이터 접근 컴포넌트임을 나타냅니다.
이 어노테이션은 다소 낯설 수 있지만, @Repository
는 @Controller
, @Service
, @Component
와 마찬가지로 객체가 Spring에 의해 관리되어야 함을 나타냅니다.
@Repository
는 데이터 접근 계층 인터페이스에 사용되며, Spring이 관리할 구현 클래스 중 하나를 할당합니다.
이는 MyBatis의 @Mapper
와 매우 유사합니다. MyBatis는 컴파일 시점에 해당 매퍼를 찾아 데이터베이스 쿼리 기능을 구현하는 프록시 클래스를 생성해야 합니다.
@Mapper
와 @Repository
는 모두 데이터 접근 계층 인터페이스에 사용됩니다.
종종 이 어노테이션이 없어도 오류가 발생하지 않는데, 이는 Spring 설정 파일에 MapperScannerConfigurer
빈이 포함되어 데이터 접근 계층 인터페이스를 스캔하고 Spring이 관리할 구현 클래스를 생성하기 때문입니다.
마찬가지로, 메인 애플리케이션 클래스에 @MapperScan
을 추가하면 MapperScannerConfigurer
와 동일한 효과를 얻을 수 있습니다.
8. @Configuration
@Configuration
어노테이션은 클래스를 설정 클래스(Configuration Class)로 선언할 때 사용됩니다. 주로 @Bean
어노테이션과 함께 사용됩니다.
예시:
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.companyname.projectname.customer.CustomerService;
import com.companyname.projectname.order.OrderService;
@Configuration
public class Application {
@Bean
public CustomerService customerService() {
return new CustomerService();
}
@Bean
public OrderService orderService() {
return new OrderService();
}
}
위 AppConfig
클래스는 다음 Spring XML과 동일합니다:
<beans>
<bean id="customerService" class="com.companyname.projectname.CustomerService"/>
<bean id="orderService" class="com.companyname.projectname.OrderService"/>
</beans>
이 어노테이션은 주로 Swagger나 MyBatis와 같은 설정에 사용됩니다.
9. @Value
@Value
어노테이션은 프로퍼티 파일이나 다른 소스에서 값을 가져와 Spring 빈에 주입할 때 사용됩니다.
예시:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class MyComponent {
@Value("${my.property}")
private String myProperty;
public void displayPropertyValue() {
System.out.println("The value of my.property is: " + myProperty);
}
}
이 예시에서 @Value("${my.property}")
는 Spring 프로퍼티의 값을 myProperty
필드에 주입합니다. 애플리케이션의 설정 파일에 “my.property”라는 프로퍼티가 있다면, 그 값이 myProperty
필드에 주입됩니다. 이 어노테이션은 코드 생성기에서 값을 하드코딩하지 않도록 자주 사용됩니다.
10. @EnableAutoConfiguration
@EnableAutoConfiguration
어노테이션은 Spring Boot의 자동 설정 메커니즘을 활성화합니다. 클래스패스 종속성과 프로퍼티를 기반으로 애플리케이션을 설정합니다.
예시:
@SpringBootApplication
@EnableAutoConfiguration
public class MyApplication {
// ...
}
@EnableAutoConfiguration
을 사용하면:
- Spring Boot가 프로젝트의 종속성과 설정을 기반으로 다양한 애플리케이션 구성 요소를 자동으로 설정합니다.
MyService
클래스가 자동으로 스캔되고 Spring 컨테이너에 의해 관리됩니다.
@EnableAutoConfiguration
이 없으면:
- 개발자가 다양한 애플리케이션 구성 요소를 수동으로 설정해야 하므로 개발 부담이 증가합니다.
MyService
클래스는 자동으로 스캔되지 않으며, Spring 컨테이너 관리에 명시적으로 구성해야 합니다.
특정 자동 설정 클래스를 제외하려면, @EnableAutoConfiguration
의 exclude
속성을 사용할 수 있습니다:
예시:
@EnableAutoConfiguration(excludeName = {
"org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration",
"org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration"
})
11. @GetMapping, @PostMapping, @PutMapping, @DeleteMapping
이 어노테이션들은 특정 HTTP 메서드를 핸들러 메서드에 매핑할 때 사용됩니다. 해당 HTTP 메서드의 단축키입니다.
예시:
@RestController
@RequestMapping("/api")
public class MyController {
@GetMapping("/hello")
public String hello() {
return "Hello, World!";
}
@PostMapping("/data")
public void saveData(@RequestBody Data data) {
// Save data
}
}
12. @PathVariable
@PathVariable
어노테이션은 메서드 매개변수를 URL 경로 변수에 바인딩할 때 사용됩니다.
메서드 매개변수 이름과 URL 변수 이름이 일치하는 예시:
@RestController
@RequestMapping("/api")
public class MyController {
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) {
// Retrieve user by given ID
}
}
메서드 매개변수 이름과 URL 변수 이름이 다른 예시:
@RestController
@RequestMapping("/api")
public class MyController {
@GetMapping("/users/{id}")
public User getUser(@PathVariable("id") Long userId) {
// Retrieve user by given ID
}
}
13. @RequestParam
@RequestParam
어노테이션은 메서드 매개변수를 요청 파라미터에 바인딩할 때 사용됩니다.
예시:
@RestController
@RequestMapping("/api")
public class MyController {
@GetMapping("/users")
public List<User> getUsers(@RequestParam("status") String status) {
// Retrieve users by given status
}
}
@RequestParam
과 @PathVariable
의 차이점:
@RequestParam
- 쿼리 파라미터에서 값을 가져옵니다.
- 쿼리 파라미터는 일반적으로 URL의 ? 기호 뒤에 전달됩니다 (예: ?name=John&age=25).
- 메서드 매개변수에 사용되며, Spring이 해당 값을 자동으로 주입합니다.
- 간단한 데이터 타입과 GET 또는 POST 요청에서 주로 사용됩니다.
예시:
@GetMapping("/users")
public String getUserByName(@RequestParam("name") String name) {
// Retrieve user by name
return "User name: " + name;
}
요약:
@PathVariable
: URL 경로에서 값을 추출할 때 사용합니다.@RequestParam
: URL 쿼리 매개변수에서 값을 추출할 때 사용합니다.
14. @RequestBody
@RequestBody
어노테이션은 요청 본문을 메서드 매개변수에 바인딩할 때 사용됩니다. 주로 RESTful API에서 JSON 또는 XML 페이로드를 받을 때 사용됩니다.
예시:
@RestController
@RequestMapping("/api")
public class MyController {
@PostMapping("/users")
public void createUser(@RequestBody User user) {
// Create a new user
}
}
이 예시에서 Spring은 요청 본문을 User
객체로 자동 변환합니다. 요청의 Content-Type이 application/json
인 경우, 요청 본문은 다음과 같습니다:
{
"name": "xiaou",
"age": 25
}
@RequestParam
과 @RequestBody
의 차이점:
@RequestParam
- 쿼리 파라미터에서 값을 가져옵니다.
- 주로 간단한 데이터 타입에 사용됩니다.
- GET 요청과 쿼리 파라미터가 있는 POST 요청을 처리할 때 적합합니다.
예시:
@GetMapping("/users")
public String getUserByName(@RequestParam("name") String name) {
// Retrieve user by name
return "User name: " + name;
}
@RequestBody
- 요청 본문에서 값을 가져옵니다.
- 주로 JSON 또는 XML과 같은 복잡한 데이터 타입에 사용됩니다.
- 큰 페이로드나 복잡한 페이로드가 있는 POST 요청을 처리할 때 적합합니다.
예시:
@PostMapping("/users")
public String createUser(@RequestBody User user) {
// Process received user object
return "User created: " + user.toString();
}
요약:
@PathVariable
: URL 경로에서 매개변수를 가져옵니다.@RequestParam
: URL 쿼리 문자열에서 매개변수를 가져옵니다.@RequestBody
: HTTP 요청 본문에서 매개변수를 가져옵니다.
15. @Qualifier
@Qualifier
어노테이션은 동일한 타입의 여러 빈이 있을 때, 어떤 빈을 주입할지 지정할 때 사용됩니다.
예시:
@Component("fooFormatter")
public class FooFormatter implements Formatter {
public String format() {
return "foo";
}
}
@Component("barFormatter")
public class BarFormatter implements Formatter {
public String format() {
return "bar";
}
}
@Component
public class FooService {
@Autowired
@Qualifier("fooFormatter")
private Formatter formatter;
// Additional code
}
이 예시에서 @Qualifier("fooFormatter")
는 fooFormatter
빈이 FooService
에 주입되도록 보장합니다.
16. @ConditionalOnProperty
@ConditionalOnProperty
어노테이션은 프로퍼티 값에 따라 빈 또는 설정을 조건부로 활성화하거나 비활성화할 때 사용됩니다.
예시:
@Configuration
@ConditionalOnProperty(name = "my.feature.enabled", havingValue = "true")
public class MyConfiguration {
// Configuration that is enabled only if my.feature.enabled is true
}
17. @Scheduled
@Scheduled
어노테이션은 메서드의 실행을 일정한 간격으로 예약할 때 사용됩니다.
예시:
@Component
public class MyScheduler {
@Scheduled(fixedDelay = 5000)
public void doSomething() {
// Task executed at fixed intervals
}
}
18. @Cacheable, @CachePut, @CacheEvict
이 어노테이션들은 메서드 결과를 캐싱할 때 사용됩니다. 메서드 반환 값을 캐싱하고, 캐시를 업데이트하거나 캐시에서 항목을 제거할 수 있습니다.
예시:
@Service
public class MyService {
@Cacheable("users")
public User getUserById(Long id) {
// Retrieve user from database
}
@CachePut("users")
public User updateUser(User user) {
// Update user in database and cache
}
@CacheEvict("users")
public void deleteUser(Long id) {
// Delete user from database and cache
}
}
웹 어노테이션 (Web Annotations)
1. @CookieValue
@CookieValue
어노테이션은 HTTP 요청에서 특정 쿠키 값을 추출하는 데 사용됩니다.
예시:
@GetMapping("/showUser")
public String showUser(@CookieValue("username") String username) {
// 추출된 쿠키 값을 사용하는 로직
return "User: " + username;
}
2. @ModelAttribute
@ModelAttribute
어노테이션은 요청 매개변수를 모델 객체에 바인딩하는 데 사용됩니다. 주로 폼 데이터를 핸들러 메서드에 전달할 때 유용합니다.
예시:
@PostMapping("/saveUser")
public String saveUser(@ModelAttribute User user) {
// 사용자 저장 로직
return "redirect:/users";
}
3. @ResponseStatus
@ResponseStatus
어노테이션은 핸들러 메서드나 예외에 대한 HTTP 상태 코드를 지정하는 데 사용됩니다.
예시:
@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
// 사용자 정의 예외
}
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public String handleResourceNotFoundException() {
return "resourceNotFound";
}
}
4. @ExceptionHandler
@ExceptionHandler
어노테이션은 컨트롤러에서 특정 예외를 처리하는 메서드를 정의하는 데 사용됩니다.
예시:
@Controller
public class MyController {
@ExceptionHandler(Exception.class)
public ModelAndView handleException(Exception ex) {
ModelAndView modelAndView = new ModelAndView("error");
modelAndView.addObject("errorMessage", ex.getMessage());
return modelAndView;
}
}
데이터 어노테이션 (Data Annotations)
1. @Entity
클래스를 JPA 엔티티로 표시하는 어노테이션입니다. 주로 데이터베이스 테이블에 매핑됩니다.
예시:
@Entity
@Table(name = "employees")
public class Employee {
// 엔티티 속성과 메서드
}
2. @Table
엔티티가 매핑되는 테이블의 세부 정보를 지정하는 어노테이션입니다.
예시:
@Entity
@Table(name = "products", schema = "inventory")
public class Product {
// 엔티티 속성과 메서드
}
3. @Id
엔티티의 기본 키를 지정하는 어노테이션입니다.
예시:
@Entity
@Table(name = "employees")
public class Employee {
@Id
private Long id;
// 기타 속성과 메서드
}
4. @GeneratedValue
기본 키의 생성 전략을 지정하는 어노테이션입니다.
예시:
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// 기타 속성과 메서드
}
5. @Column
필드가 매핑되는 컬럼의 세부 정보를 지정하는 어노테이션입니다.
예시:
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "emp_name", length = 50, nullable = false)
private String name;
// 기타 속성과 메서드
}
6. @Transient
필드가 데이터베이스에 영속되지 않도록 지정하는 어노테이션입니다.
예시:
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "emp_name", length = 50, nullable = false)
private String name;
@Transient
private String transientField;
// 기타 속성과 메서드
}
7. @PersistenceContext
엔티티 매니저를 주입하여 엔티티 영속성 작업을 관리하는 어노테이션입니다.
예시:
@Service
public class EmployeeService {
@PersistenceContext
private EntityManager entityManager;
// 기타 메서드
}
8. @Query
커스텀 JPQL(Java Persistence Query Language) 쿼리를 선언하는 어노테이션입니다.
리포지토리 인터페이스 또는 엔티티 클래스의 메서드에 사용할 수 있습니다.
예시:
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
@Query("SELECT e FROM Employee e WHERE e.department = ?1")
List<Employee> findByDepartment(Department department);
}
9. @NamedQuery
엔티티 클래스에서 이름이 지정된 쿼리를 선언하는 어노테이션입니다.
이름이 지정된 쿼리는 여러 곳에서 참조할 수 있는 미리 정의된 JPQL 쿼리입니다.
예시:
@Entity
@NamedQuery(name = "Employee.findAll", query = "SELECT e FROM Employee e")
public class Employee {
// 엔티티 속성과 메서드
}
10. @Param
JPQL 쿼리에서 명명된 매개변수를 참조하는 어노테이션입니다.
@Query
어노테이션 내에서 사용되며, 쿼리 문자열에서 명명된 매개변수와 함께 사용됩니다.
예시:
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
@Query("SELECT e FROM Employee e WHERE e.department = :dept")
List<Employee> findByDepartment(@Param("dept") Department department);
}
11. @JoinTable
엔티티 간의 다대다 관계를 위한 조인 테이블의 세부 정보를 지정하는 어노테이션입니다.
예시:
@Entity
public class Student {
@ManyToMany
@JoinTable(name = "student_course",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "course_id"))
private List<Course> courses;
// 기타 속성과 메서드
}
12. @JoinColumn
일대다 또는 일대일 관계에서 엔티티 연관을 위한 외래 키 컬럼을 지정하는 어노테이션입니다.
예시:
@Entity
public class Employee {
@ManyToOne
@JoinColumn(name = "department_id")
private Department department;
// 기타 속성과 메서드
}
검증 어노테이션 (Validation Annotations)
이 어노테이션들은 일반적으로 Bean Validation(JSR-380) 사양에서 자바 빈 속성을 검증하는 데 사용됩니다.
1. @Valid
이 어노테이션은 중첩된 객체의 속성도 함께 검증해야 함을 나타냅니다. 주로 복잡한 객체의 모든 속성을 검증하기 위해 사용됩니다.
예시:
public class Address {
@NotNull
private String street;
// 기타 속성과 메서드
}
public class User {
@Valid
private Address address;
// 기타 속성과 메서드
}
2. @NotNull
이 어노테이션은 속성 값이 null이 아님을 검증하는 데 사용됩니다. 주로 문자열, 컬렉션, 맵, 기본 데이터 타입에 적용됩니다.
예시:
public class User {
@NotNull
private String username;
// 기타 속성과 메서드
}
3. @Size
이 어노테이션은 속성 값의 크기가 지정된 범위 내에 있는지 검증하는 데 사용됩니다. 문자열, 컬렉션, 맵, 배열 속성에 적용할 수 있습니다.
예시:
public class User {
@Size(min = 2, max = 50)
private String name;
// 기타 속성과 메서드
}
4. @Min
이 어노테이션은 속성 값이 지정된 최소값 이상임을 검증하는 데 사용됩니다. 주로 숫자 속성에 사용됩니다.
예시:
public class User {
@Min(18)
private int age;
// 기타 속성과 메서드
}
5. @Max
이 어노테이션은 속성 값이 지정된 최대값 이하임을 검증하는 데 사용됩니다. 주로 숫자 속성에 사용됩니다.
예시:
public class User {
@Max(100)
private int age;
// 기타 속성과 메서드
}
6. @Email
이 어노테이션은 속성 값이 이메일 주소 형식에 맞는지 검증하는 데 사용됩니다. 주로 문자열 속성에 적용됩니다.
예시:
public class User {
@Email
private String email;
// 기타 속성과 메서드
}
7. @Pattern
이 어노테이션은 속성 값이 지정된 정규 표현식 패턴과 일치하는지 검증하는 데 사용됩니다. 사용자 정의 검증 규칙을 허용합니다.
예시:
public class User {
@Pattern(regexp = "^[A-Za-z0-9]+$")
private String username;
// 기타 속성과 메서드
}
보안 어노테이션 (Security Annotations)
이 어노테이션들은 Spring Security와 OAuth2 프레임워크에서 보안 관련 기능과 인증 메커니즘을 설정하는 데 주로 사용됩니다.
1. @EnableWebSecurity
Spring Security의 웹 보안을 활성화합니다. 일반적으로 설정 클래스에 사용하여 Spring Boot 애플리케이션에서 Spring Security를 사용할 수 있도록 합니다.
예시:
@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
// 보안 규칙 등을 설정합니다.
}
2. @Configuration
클래스가 설정 클래스임을 나타냅니다. 다른 어노테이션과 함께 사용되어 빈을 정의하고 애플리케이션의 다양한 기능을 구성합니다.
예시:
@Configuration
public class AppConfig {
// 빈을 정의합니다.
}
3. @EnableGlobalMethodSecurity
전역 메서드 수준 보안을 활성화합니다. PreAuthorize
, PostAuthorize
, Secured
, RolesAllowed
어노테이션을 구성할 수 있습니다.
예시:
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
// 메서드 수준 보안 규칙을 설정합니다.
}
4. @PreAuthorize
메서드 실행 전에 인증 검사를 수행하는 데 사용됩니다. Spring Expression Language(SpEL)를 사용하여 접근 규칙을 지정할 수 있습니다.
예시:
@PreAuthorize("hasRole('ROLE_ADMIN')")
public void deleteUser(User user) {
// 사용자를 삭제하는 로직
}
5. @PostAuthorize
메서드 실행 후에 인증 검사를 수행하는 데 사용됩니다. Spring Expression Language(SpEL)를 사용하여 접근 규칙을 지정할 수 있습니다.
예시:
@PostAuthorize("returnObject.owner == authentication.name")
public Object findDocument() {
// 문서를 반환하는 로직
}
6. @Secured
특정 역할이 메서드를 호출할 수 있도록 접근을 제한하는 데 사용됩니다.
예시:
@Secured("ROLE_ADMIN")
public void deleteUser(User user) {
// 사용자를 삭제하는 로직
}
7. @RolesAllowed
특정 역할이 메서드를 호출할 수 있도록 접근을 제한하는 데 사용됩니다.
예시:
@RolesAllowed("ROLE_ADMIN")
public void deleteUser(User user) {
// 사용자를 삭제하는 로직
}
8. @EnableOAuth2Client, @EnableResourceServer, @EnableAuthorizationServer
이 어노테이션들은 OAuth2 구성을 위해 사용되며, OAuth2 클라이언트, 리소스 서버, 인증 서버 기능을 활성화합니다. 주로 설정 클래스에 사용됩니다.
예시:
@Configuration
@EnableOAuth2Client
public class OAuth2ClientConfig {
// OAuth2 클라이언트를 설정합니다.
}
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
// 리소스 서버를 설정합니다.
}
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
// 인증 서버를 설정합니다.
}
이렇게 하면, Spring Security와 OAuth2 설정을 더욱 쉽게 관리할 수 있습니다.
테스트 어노테이션 (Testing Annotations)
JUnit과 Spring 프레임워크에서 테스트 관련 기능을 위해 자주 사용하는 어노테이션입니다.
1. @RunWith
JUnit 4에서 테스트 러너를 지정할 때 사용합니다. JUnit 5에서는 @ExtendWith
로 대체되었습니다.
예시:
@RunWith(SpringRunner.class)
public class MySpringTest {
// 테스트 코드
}
2. @SpringBootTest
통합 테스트를 위해 전체 Spring 애플리케이션 컨텍스트를 시작할 때 사용합니다. 애플리케이션 컨텍스트를 자동으로 구성합니다.
예시:
@SpringBootTest
public class MyIntegrationTest {
// 통합 테스트 코드
}
3. @WebMvcTest
Spring MVC 애플리케이션의 단위 테스트를 수행할 때 사용합니다. 컨트롤러와 필터 같은 웹 관련 컴포넌트만 로드합니다.
예시:
@WebMvcTest(UserController.class)
public class UserControllerTest {
// 컨트롤러 단위 테스트 코드
}
4. @DataJpaTest
JPA 영속 계층의 단위 테스트를 수행할 때 사용합니다. 메모리 내 데이터베이스(H2 등)를 자동으로 구성하고 @Entity
어노테이션을 스캔합니다.
예시:
@DataJpaTest
public class UserRepositoryTest {
// JPA 단위 테스트 코드
}
5. @RestClientTest
Spring RestTemplate
또는 WebClient
클라이언트의 단위 테스트를 수행할 때 사용합니다. RestTemplate
또는 WebClient
빈을 자동으로 구성합니다.
예시:
@RestClientTest(MyRestClient.class)
public class MyRestClientTest {
// Rest 클라이언트 단위 테스트 코드
}
6. @MockBean
모의 객체를 생성하고 이를 Spring 컨텍스트에 주입할 때 사용됩니다. 단위 테스트를 위해 Spring 빈을 대체합니다.
예시:
@SpringBootTest
public class MyServiceTest {
@MockBean
private SomeDependency mockDependency;
// 단위 테스트 코드
}
7. @AutoConfigureMockMvc
Spring MVC 테스트에서 MockMvc
를 자동으로 구성할 때 사용됩니다. 컨트롤러에 대한 요청을 시뮬레이션하는 데 사용됩니다.
예시:
@WebMvcTest(UserController.class)
@AutoConfigureMockMvc
public class UserControllerTest {
@Autowired
private MockMvc mockMvc;
// 컨트롤러 테스트 코드
}
8. @Test, @Before, @After, @BeforeEach, @AfterEach, @BeforeAll, @AfterAll:
JUnit 테스트 메서드의 생명주기 관리를 위해 사용됩니다. @Test
는 테스트 메서드를 표시하고, 다른 어노테이션은 테스트 메서드 전후에 특정 작업을 실행합니다.
예시:
@Test
public void testSomething() {
// 테스트 메서드
}
@BeforeEach
public void setUp() {
// 각 테스트 메서드 전의 작업
}
@AfterEach
public void tearDown() {
// 각 테스트 메서드 후의 작업
}
9. @DisplayName
테스트 클래스나 테스트 메서드에 사용자 정의 이름을 지정할 때 사용됩니다. 보다 의미 있는 테스트 보고서를 생성하는 데 사용됩니다.
예시:
@Test
@DisplayName("사용자 등록 기능 테스트")
public void testUserRegistration() {
// 테스트 메서드
}
10. @Disabled
테스트 클래스나 테스트 메서드를 비활성화할 때 사용됩니다. 디버깅 또는 개발 중에 특정 테스트를 일시적으로 건너뛰어야 할 때 사용됩니다.
예시:
@Test
@Disabled("임시 비활성화, 수정 대기 중")
public void testSomething() {
// 테스트 메서드
}
11. @ParameterizedTest, @ValueSource, @CsvSource
매개변수화된 테스트를 위해 사용되며, 동일한 테스트 메서드를 여러 번 실행할 수 있게 합니다. @ValueSource
는 단일 매개변수 값을 지정하고, @CsvSource
는 여러 매개변수 값을 지정합니다.
예시:
@ParameterizedTest
@ValueSource(strings = {"apple", "banana", "orange"})
public void testFruit(String fruit) {
// 다른 과일 매개변수를 사용하는 테스트 메서드
}
@ParameterizedTest
@CsvSource({"apple, 1", "banana, 2", "orange, 3"})
public void testFruit(String fruit, int count) {
// 과일과 개수 매개변수를 사용하는 테스트 메서드
}
12. @ExtendWith
테스트 런타임의 기능을 확장할 때 사용됩니다. 예를 들어, 매개변수 해석 및 조건 평가와 같은 기능을 추가합니다.
예시:
@ExtendWith(MyExtension.class)
public class MyTest {
// 테스트 메서드
}
메시지 어노테이션 (Messaging Annotations)
이 어노테이션들은 Spring 프레임워크에서 JMS(Java Message Service) 메시징 기능을 위해 자주 사용되며, JMS 메시지의 생산과 소비를 간단하게 만들어 줍니다.
1. @EnableJms
@EnableJms
어노테이션은 JMS 기능을 활성화합니다. 주로 설정 클래스에 배치하여 JMS 관련 어노테이션의 지원을 활성화합니다.
예시:
@Configuration
@EnableJms
public class AppConfig {
// 기타 설정 코드
}
2. @JmsListener
@JmsListener
어노테이션은 JMS 메시지를 수신하는 메서드를 선언합니다. 수신할 큐 또는 토픽을 지정할 수 있습니다.
예시:
@JmsListener(destination = "myQueue")
public void receiveMessage(String message) {
// 수신한 메시지 처리
}
3. @SendTo
@SendTo
어노테이션은 메시지 처리 메서드에서 응답 메시지의 목적지를 지정합니다. 주로 @JmsListener
와 함께 사용됩니다.
예시:
@JmsListener(destination = "inputQueue")
@SendTo("outputQueue")
public String handleMessage(String message) {
// 메시지를 처리하고 결과 반환
}
4. @MessageMapping
@MessageMapping
어노테이션은 특정 목적지의 메시지를 처리하는 메서드를 식별합니다. 주로 Spring의 WebSocket 지원과 함께 WebSocket 메시지를 처리하는 데 사용됩니다.
예시:
@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Greeting greeting(HelloMessage message) {
// 메시지를 처리하고 결과 반환
}
5. @Payload
@Payload
어노테이션은 JMS 메시지 처리 메서드에서 페이로드 매개변수를 지정하여 JMS 메시지 내용을 가져오는 데 사용됩니다.
예시:
@JmsListener(destination = "myQueue")
public void receiveMessage(@Payload String message) {
// 메시지 내용 처리
}
6. @Header
@Header
어노테이션은 JMS 메시지 처리 메서드에서 헤더 매개변수를 지정하여 JMS 메시지 헤더 정보를 가져오는 데 사용됩니다.
예시:
@JmsListener(destination = "myQueue")
public void receiveMessage(@Header("X-Custom-Header") String customHeader) {
// 메시지 헤더 처리
}
이 어노테이션들을 통해 Spring 프레임워크에서 JMS 메시징을 더욱 효율적으로 사용할 수 있습니다.
AOP 어노테이션 (Aspect-Oriented Programming Annotations)
이 어노테이션들은 Spring 프레임워크에서 AOP(관점 지향 프로그래밍)를 위해 자주 사용되며, 여러 곳에서 반복적으로 사용되는 코드를 모듈화하는 데 유용합니다.
1. @Aspect
횡단 관심사를 캡슐화하는 Aspect를 정의합니다. Aspect는 포인트컷과 어드바이스를 포함하는 클래스입니다.
예시:
@Aspect
@Component
public class LoggingAspect {
// 어스펙트 클래스 구현
}
2. @Pointcut
Aspect 로직이 적용될 지점을 정의합니다. 동일한 포인트컷을 여러 어드바이스에서 재사용할 수 있습니다.
예시:
@Pointcut("execution(* com.example.service.*.*(..))")
private void serviceLayer() {}
3. @Before
메서드 실행 전에 실행되는 ‘before’ 어드바이스를 정의합니다. 조인 포인트 전에 실행됩니다.
예시:
@Before("serviceLayer()")
public void beforeAdvice() {
// 'before' 어드바이스 로직
}
4. @After
메서드 실행 후에 실행되는 ‘after’ 어드바이스를 정의합니다. 메서드의 결과와 상관없이 조인 포인트 후에 실행됩니다.
예시:
@After("serviceLayer()")
public void afterAdvice() {
// 'after' 어드바이스 로직
}
5. @AfterReturning
메서드가 정상적으로 반환된 후에 실행되는 ‘returning’ 어드바이스를 정의합니다. 메서드가 정상적으로 반환될 때만 실행됩니다.
예시:
@AfterReturning(pointcut = "serviceLayer()", returning = "result")
public void afterReturningAdvice(Object result) {
// 'returning' 어드바이스 로직
}
6. @AfterThrowing
메서드가 예외를 던진 후에 실행되는 ‘throwing’ 어드바이스를 정의합니다. 메서드가 예외를 던질 때만 실행됩니다.
예시:
@AfterThrowing(pointcut = "serviceLayer()", throwing = "exception")
public void afterThrowingAdvice(Exception exception) {
// 'throwing' 어드바이스 로직
}
7. @Around
메서드 실행 전후에 실행되는 ‘around’ 어드바이스를 정의합니다. 이 어드바이스는 메서드 실행을 제어합니다.
예시:
@Around("serviceLayer()")
public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
// 실행 전 로직
Object result = joinPoint.proceed(); // 어드바이스된 메서드 실행
// 실행 후 로직
return result;
}
이 어노테이션들은 자주 사용되지는 않지만, 간단히 요약해두었습니다.
엑추에이터 어노테이션 (Actuator Annotations)
Spring Boot Actuator를 활성화하고 맞춤 설정하기 위해 사용하는 어노테이션입니다. 이 어노테이션을 사용하면 애플리케이션의 모니터링과 관리 기능을 제공할 수 있습니다.
@EnableActuator
Spring Boot Actuator 모듈을 활성화하여 애플리케이션 모니터링 및 관리 기능을 제공합니다.
@Endpoint
커스텀 엔드포인트를 생성하여 사용자 정의 모니터링 및 관리 엔드포인트를 노출합니다.
예시:
@Endpoint(id = "customEndpoint")
public class CustomEndpoint {
@ReadOperation
public String read() {
return "Custom Read Operation";
}
}
@RestControllerEndpoint
REST 스타일의 엔드포인트를 생성하여 REST 컨트롤러로 사용할 수 있게 합니다.
예시:
@RestControllerEndpoint(id = "customRestEndpoint")
public class CustomRestEndpoint {
@GetMapping("/custom")
public String custom() {
return "Custom REST Endpoint";
}
}
@ReadOperation
엔드포인트에서 GET 요청을 처리하는 메서드를 지정합니다.
@WriteOperation
엔드포인트에서 POST 요청을 처리하는 메서드를 지정합니다.
@DeleteOperation
엔드포인트에서 DELETE 요청을 처리하는 메서드를 지정합니다.
설정 속성 어노테이션 (Configuration Properties Annotations)
설정 파일의 속성을 Java Bean에 매핑하기 위해 사용하는 어노테이션입니다.
@ConfigurationProperties
설정 파일의 속성을 Java Bean에 매핑합니다.
예시:
@ConfigurationProperties(prefix = "app")
public class AppProperties {
private String name;
private String version;
// Getters and setters
}
@ConstructorBinding
설정 속성을 생성자 매개변수에 바인딩합니다. 일반적으로 @ConfigurationProperties
와 함께 사용됩니다.
@Validated
설정 속성 클래스를 검증 대상으로 표시합니다. 일반적으로 JSR-380(Bean Validation)과 함께 사용됩니다.
국제화 및 현지화 어노테이션 (Internationalization and Localization)
@EnableMessageSource
: 메시지 소스 처리를 활성화하며, 주로 국제화와 지역화를 위해 사용됩니다.@EnableWebMvc
: Spring MVC 기능을 활성화하며, 주로 설정 클래스에서 Spring MVC 지원을 위해 사용됩니다.@LocaleResolver
: 요청에서 로케일 정보를 해석합니다.@MessageBundle
: 국제화 메시지 리소스 파일의 기본 이름을 지정합니다.@MessageSource
: 메시지 리소스를 가져오며, 주로@Autowired
와 함께 사용됩니다.
로깅 모니터링 어노테이션 (Logging and Monitoring)
@Slf4j
, @Log4j2
, @Log
:
다양한 로깅 프레임워크(SLF4J, Log4j2, JDK Logging)를 위한 로거 생성을 단순화합니다.
예시:
@Slf4j
public class MyService {
public void doSomething() {
log.info("Doing something");
}
}
@Timed
, @Counted
, @ExceptionMetered
:
메서드 실행 시간, 호출 횟수, 예외 등을 모니터링하는 메트릭을 추가합니다.
데이터 검증 어노테이션 (Data Validation)
@NotNull
, @NotBlank
, @Email
, @Size
, @Pattern
:
필드의 null 아님, 공백 아님, 이메일 형식, 크기 범위, 정규식 패턴 일치를 검증합니다.
@Positive
, @PositiveOrZero
, @Negative
, @NegativeOrZero
:
숫자가 양수, 음수가 아닌지, 음수, 음수가 아닌지 검증합니다.
그래프QL 어노테이션 (GraphQL Annotations)
@GraphQLApi
: 클래스를 GraphQL API 클래스로 표시합니다.@GraphQLQuery
,@GraphQLMutation
,@GraphQLSubscription
: GraphQL 쿼리, 뮤테이션, 구독을 정의합니다.@GraphQLArgument
,@GraphQLContext
,@GraphQLNonNull
,@GraphQLInputType
,@GraphQLType
: GraphQL 인자, 컨텍스트, null 아님 타입, 입력 타입, 타입을 정의합니다.
통합 어노테이션 (Integration Annotations)
@IntegrationComponentScan
: 통합 컴포넌트를 스캔합니다.@MessagingGateway
,@Transformer
,@Splitter
,@Aggregator
,@ServiceActivator
,@InboundChannelAdapter
,@OutboundChannelAdapter
,@Router
,@BridgeTo
: 통합 컴포넌트를 구성하고 정의합니다.
Flyway 데이터베이스 관련 어노테이션 (Flyway Database Migration)
@FlywayTest
: Flyway 데이터베이스 마이그레이션을 테스트합니다.@FlywayTestExtension
: Flyway 테스트 기능을 확장합니다.@FlywayTestExtension.Test
,@FlywayTestExtension.BeforeMigration
,@FlywayTestExtension.AfterMigration
: 테스트 메서드를 표시하고 마이그레이션 전후에 실행합니다.
JUnit 5 어노테이션 (JUnit5 Annotations)
@ExtendWith
: JUnit 5 기능을 확장합니다.@TestInstance
: 테스트 인스턴스의 생명 주기를 구성합니다.@TestTemplate
: 테스트 템플릿 메서드를 지정합니다.@DisplayNameGeneration
: 테스트 표시 이름을 생성하는 전략을 사용자 지정합니다.@Nested
: 중첩 테스트 클래스를 생성합니다.@Tag
: 태그를 기반으로 테스트를 실행하도록 표시합니다.@DisabledOnOs
,@EnabledOnOs
,@DisabledIf
,@EnabledIf
: 조건에 따라 테스트를 활성화하거나 비활성화합니다.
API 문서 어노테이션 (API Documentation Annotations)
@Api
,@ApiOperation
,@ApiParam
,@ApiModel
,@ApiModelProperty
: API 문서화 세부 사항을 정의하고 설명합니다.
예외 처리 어노테이션 (Exception Handling Annotations)
@ControllerAdvice
: 전역 예외 처리기를 정의합니다.@ExceptionHandler
: 특정 예외를 처리합니다.
그래프QA (추가)어노테이션 (GraphQL Annotations (Additional))
@GraphQLSchema
,@GraphQLQueryResolver
,@GraphQLMutationResolver
,@GraphQLSubscriptionResolver
,@GraphQLResolver
: GraphQL 스키마와 리졸버를 정의합니다.
Server-Sent Events (SSE) Annotations
@SseEmitter
: SSE 이벤트 방출기를 생성합니다.@SseEventSink
: SSE 이벤트 수신기를 주입합니다.
웹플럭스 어노테이션 (WebFlux Annotations)
@RestController
,@GetMapping
,@PostMapping
,@PutMapping
,@DeleteMapping
,@PatchMapping
: WebFlux RESTful 컨트롤러와 요청 매핑을 정의합니다.
미터링 어노테이션 (Metering Annotations)
@Timed
: 메서드 실행 시간을 측정합니다.@Counted
: 메서드 호출 횟수를 셉니다.@Gauge
: 메서드를 게이지 메트릭으로 노출합니다.@ExceptionMetered
: 메서드 예외 발생률을 측정합니다.
마무리
이 목록은 모든 것을 포함한 것은 아닙니다. Spring Boot는 다양한 모듈과 기능에 걸쳐 수많은 어노테이션을 제공합니다. 포괄적인 목록과 자세한 사용법은 공식 Spring Boot 문서와 모듈별 가이드를 참조하시기 바랍니다.
이 글에서는 일반적으로 많이 사용하는 어노테이션들을 다루고 있으며, 일반적인 프로젝트에서 접할 수 있는 거의 모든 어노테이션을 포함하였습니다.
Spring Boot는 기능이 매우 광범위하므로 필요할 때마다 공식 문서를 참고하여 최신 정보를 확인하는 것이 중요합니다. 어노테이션을 적절히 활용하면 개발 생산성을 크게 높일 수 있으므로, 각 어노테이션의 특징과 용도를 이해하고 프로젝트에 맞게 잘 활용해 보세요.
더 궁금한 점이 있거나 도움이 필요하시면 언제든지 댓글로 남겨주세요. 읽어주셔서 감사합니다! 🙂