Spring (Boot)

@PostConstruct 의 사용 이유

superbono 2021. 12. 26. 15:01

@PostConstruct란?

종속성 주입이 완료된 후 실행되어야 하는 메서드에 사용된다. 이 어노테이션은 다른 리소스에서 호출되지 않아도 수행된다. 

 

@PostConstruct의 사용 이유

1) 생성자가 호출되었을 때, 빈은 초기화되지 않았음(의존성 주입이 이루어지지 않았음) 

이럴 때 @PostConstruct를 사용하면 의존성 주입이 끝나고 실행됨이 보장되므로 빈의 초기화에 대해서 걱정할 필요가 없다. 

2) bean 의 생애주기에서 오직 한 번만 수행된다는 것을 보장한다. (어플리케이션이 실행될 때 한번만 실행됨)

따라서 bean이 여러 번 초기화되는 걸 방지할 수 있다.

 

@PostConstruct의 사용 예

@Component
public class DbInit {

    @Autowired
    private UserRepository userRepository;

    @PostConstruct
    private void postConstruct() {
        User admin = new User("admin", "admin password");
        User normalUser = new User("user", "user password");
        userRepository.save(admin, normalUser);
    }
}

 

userRepository의 bean 초기화가 완료된 뒤 수행됨이 보장되므로 의존성 주입이 완료되었는지에 대해서 염려할 필요가 없다. 

 

+) 직접 사용했던 경험

처음에 어플리케이션이 실행되면서 db 스크립트로 테이블이 생성되는 코드였는데, @PostConstruct 가 붙은 클래스에서 오류가 났다.

알고보니 db 스크립트가 뜨면서 테이블이 생성되는 것과 postConstruct가 붙은 클래스의 @Autowired로 의존성을 주입받아야 하는 것의 싱크가 어긋나서였다. 테이블이 생성되고, 해당 repository의 의존성을 주입받아야 하는 순서인데, 어떠한 이유로 테이블이 나중에 생성되고 클래스 객체가 먼저 생성된 것이었다. 따라서 의존성 주입을 먼저 수행되고 클래스 객체가 만들어져야 하는 @PostConstruct에서 의존성 주입이 안되니까 에러를 뱉는 경우였다.

따라서 ApplicationReadyEvent를 받고, 해당 클래스가 실행되도록(db 스크립트 다 실행된 뒤 해당 클래스가 실행되게끔) 해결했다. @PostConstruct가 의존성 주입은 보장하지만, db 스크립트의 완전한 수행을 보장하지는 않으므로 가아아끔 이런 경우가 일어날 수도 있는 것 같다. 어노테이션 붙이면 알아서 스프링이 해결해주니까 대충 알게되는데, 어노테이션에 대해서도 완전히 잘 알아야겠다는 생각을 했다.

 

 

참고 -  https://www.baeldung.com/spring-postconstruct-predestroy

 

 

'Spring (Boot)' 카테고리의 다른 글

Filter 와 Interceptor의 차이점  (0) 2021.12.07