legacy/Spring

[Spring] @PostConstruct 호출 순서

heemang_e 2023. 7. 8. 10:35

 

@PostConstruct가 뭐야?

의존성 주입(DI)이 완료된 후 호출되어야 하는 메서드에 사용하는 애너테이션이다.

예를 들어 로컬환경에서 테스트할 때, 매번 같은 행동(ex. 가입된 사용자)을 반복할 필요 없이 @PostConstruct가 붙은 메서드에 반복되는 코드를 작성하면 된다.

 

@PostConstruct 호출 순서

  1. 생성자 호출
  2. 의존성 주입
  3. @PostConstruct 메서드 호출

다음은 실제로 호출되는 과정이다.

 

Repository

@Repository
@Slf4j
public class UserRepository {

    private Map<Long, User> stored = new HashMap<>();
    private static Long sequence = 0L;

    public UserRepository(Map<Long, User> stored) {
        log.info("UserRepository 생성자 호출");
        this.stored = stored;
    }

    public User save(User user) {
        user.setId(++sequence);
        stored.put(user.getId(), user);
        return user;
    }
}

테스트 클래스

@Slf4j
@SpringBootTest
public class PostConstructTest {

    private final UserRepository userRepository;

    @Autowired
    public PostConstructTest(UserRepository userRepository) {
        log.info("UserRepository DI 호출");
        this.userRepository = userRepository;
    }

    @PostConstruct
    void postConstruct() {
        log.info("PostConstruct 호출");
    }

    @Test
    void postConstructCallTest() {

    }
}

 

UserRepository의 생성자, 테스트 클래스의 생성자 그리고 @PostConstruct 애너테이션 세 가지를 집중해서 보자.

UserRepostory는 애너테이션에 의해 자동으로 스프링 빈에 등록되었다. 테스트 클래스에서 스프링 컨테이너에서 UserRepository를 가져와 DI를 해주어야 하므로 @SpringBootTest 애너테이션을 사용해야 한다. 

 

결과

호출 순서

스프링 빈에 등록된 클래스의 생성자를 먼저 호출하고 DI 주입 후 @PostConstruct가 호출됨을 알 수 있다.