@Order

2025. 1. 26. 15:34Spring 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