2025. 1. 26. 15:34ㆍSpring Framework/Spring IoC
📌 Spring의 @Order 애노테이션 정리
Spring에서 @Order
애노테이션은 컴포넌트(Bean) 간의 우선순위를 지정하는 데 사용되는 기능입니다.
여러 개의 빈이 존재할 때 어떤 순서로 주입하거나 실행할지 결정할 때 활용됩니다.
1️⃣ @Order의 역할 및 기본 개념
✅ @Order
는 동일한 타입의 여러 빈(또는 객체) 간에 정렬 순서를 지정하는 데 사용됩니다.
✅ 숫자가 낮을수록 우선순위가 높음 (1 < 2 < 3
→ 1이 가장 우선적으로 실행)
✅ 주로 자동 주입(Collection, List, 배열) 시 정렬, 인터셉터 및 필터 실행 순서 지정 등에 활용됨.
✅ 빈 생성 순서와는 관련 없음 (의존성 및 @DependsOn
에 의해 결정됨).
2️⃣ @Order 사용 예제
✅ 1) 동일한 인터페이스를 구현하는 여러 빈 정렬
@Order
를 사용하면 리스트(List)로 주입될 때 실행 순서를 지정할 수 있음
public interface MyService {
void execute();
}
@Order(1) // 가장 높은 우선순위
@Component
public class HighPriorityService implements MyService {
@Override
public void execute() {
System.out.println("High Priority Service");
}
}
@Order(2) // 두 번째 우선순위
@Component
public class MediumPriorityService implements MyService {
@Override
public void execute() {
System.out.println("Medium Priority Service");
}
}
@Order(3) // 가장 낮은 우선순위
@Component
public class LowPriorityService implements MyService {
@Override
public void execute() {
System.out.println("Low Priority Service");
}
}
📌 List<MyService>
로 주입될 경우 정렬 순서:
@Component
public class ServiceExecutor {
private final List<MyService> services;
@Autowired
public ServiceExecutor(List<MyService> services) {
this.services = services;
}
public void executeAll() {
services.forEach(MyService::execute);
}
}
📌 실행 결과
High Priority Service
Medium Priority Service
Low Priority Service
✅ @Order(1)
이 가장 먼저 실행됨.
✅ 2) @Order
vs. Ordered
인터페이스
Spring에서는 @Order
애노테이션뿐만 아니라 Ordered
인터페이스를 구현하여 동적으로 우선순위를 지정할 수도 있습니다.
🔹 Ordered
인터페이스 활용 예제
@Component
public class DynamicPriorityService implements MyService, Ordered {
@Override
public void execute() {
System.out.println("Dynamically Ordered Service");
}
@Override
public int getOrder() {
return 0; // 가장 높은 우선순위
}
}
✅ Ordered
인터페이스를 사용하면, 특정 조건에 따라 우선순위를 동적으로 변경 가능
✅ @Order
는 클래스 레벨에서 하드코딩된 값이지만, Ordered
인터페이스는 런타임에서 동적으로 결정 가능
✅ 3) @Order
를 활용한 Spring Security 필터 적용 순서
Spring Security에서는 여러 개의 Filter
빈이 존재할 경우 실행 순서를 @Order
로 지정할 수 있습니다.
@Order(1)
@Component
public class FirstSecurityFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
System.out.println("Executing FirstSecurityFilter");
chain.doFilter(request, response);
}
}
@Order(2)
@Component
public class SecondSecurityFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
System.out.println("Executing SecondSecurityFilter");
chain.doFilter(request, response);
}
}
📌 필터 실행 순서
Executing FirstSecurityFilter
Executing SecondSecurityFilter
✅ 필터가 @Order
값이 낮은 순서대로 실행됨
3️⃣ @Order의 주요 특징 및 주의점
🔹 1) 디폴트 값: Ordered.LOWEST_PRECEDENCE
(Integer.MAX_VALUE)
@Order
애노테이션을 명시하지 않으면Ordered.LOWEST_PRECEDENCE
가 적용됨.- 이는 우선순위가 가장 낮은 값(Integer.MAX_VALUE) 이므로, 가장 마지막에 실행됨.
@Component
public class DefaultService implements MyService {
@Override
public void execute() {
System.out.println("Default Service (Lowest Priority)");
}
}
📌 List로 주입 시
High Priority Service
Medium Priority Service
Low Priority Service
Default Service (Lowest Priority)
✅ @Order
를 지정하지 않으면 자동으로 가장 마지막 순서로 실행됨.
🔹 2) @Order는 "빈 생성 순서"와 무관
✅ @Order
는 빈이 생성되는 순서(Startup Order)를 결정하지 않음
✅ 빈 생성 순서는 의존성 관계 및 @DependsOn
애노테이션에 의해 결정됨
@Component
@Order(1)
public class FirstBean {
public FirstBean() {
System.out.println("FirstBean Created");
}
}
@Component
@Order(2)
public class SecondBean {
public SecondBean() {
System.out.println("SecondBean Created");
}
}
📌 실행 결과 (생성 순서가 @Order와 다름)
SecondBean Created
FirstBean Created
✅ @Order(1)
을 지정해도 빈 생성 순서는 영향을 받지 않음
✅ 빈 생성 순서를 변경하려면 @DependsOn
을 활용해야 함.
@Component
@DependsOn("firstBean")
public class SecondBean { ... }
🔹 3) @Order
vs. @Priority
Spring 4.1 이후부터는 @Order
대신 자카르타 표준 애노테이션인 @Priority
를 사용할 수도 있습니다.
import jakarta.annotation.Priority;
@Priority(1)
@Component
public class PriorityService implements MyService {
@Override
public void execute() {
System.out.println("Priority Service");
}
}
✅ @Priority(1)
을 사용해도 @Order(1)
과 동일한 동작
✅ Spring 내부에서 OrderComparator
를 사용하여 @Priority
를 처리
📌 @Priority
의 주의점
- Spring 환경에서는
@Priority
가 단순 정렬 용도로 사용되지만,
CDI (Contexts and Dependency Injection) 환경에서는 단일 요소 선택에 영향을 줄 수 있음 - 따라서 Spring에서는 가능하면
@Order
를 사용하는 것이 더 안전
🎯 Summary
개념 | 설명 |
---|---|
@Order |
동일한 타입의 여러 빈을 주입받을 때 정렬 순서를 지정하는 애노테이션 |
우선순위 규칙 | 숫자가 낮을수록 높은 우선순위 (1 < 2 < 3 → 1이 먼저 실행됨) |
기본값 | Ordered.LOWEST_PRECEDENCE (Integer.MAX_VALUE) |
적용 대상 | List, 배열, 인터셉터, 필터, BeanPostProcessor 등 |
빈 생성 순서 | @Order 는 생성 순서에 영향을 주지 않음 (@DependsOn 활용) |
Ordered 인터페이스 |
getOrder() 메서드를 사용해 동적으로 우선순위 설정 가능 |
@Priority |
@Order 와 유사하지만, CDI 환경에서 단일 요소 선택에 사용될 수도 있음 |
📌 @Order
는 "정렬이 필요한 상황"에서만 적용됨 → 빈 생성 순서 변경 불가
📌 빈 생성 순서를 조정하려면 @DependsOn
사용 🚀
'Spring Framework > Spring IoC' 카테고리의 다른 글
DefaultListableBeanFactory의 확장성이란? (0) | 2025.03.06 |
---|---|
BeanPostProcessor / BeanFactoryPostProcessor (0) | 2025.03.06 |
엔터프라이즈 관련 기능 (1) | 2025.01.16 |
Service Locator Pattern (1) | 2025.01.16 |
Spring IoC (0) | 2024.11.15 |