NetworkClient라는 클래스가 있고, 이녀석은 서비스 시작 시 connect()라는 함수를, 종료시 disconnect()라는 함수를 실행하는 녀석입니다.
URL에 접속하는 친구이고, 일단 우선 url을 설정해서 접속해보는 상황으로 만들어보겠습니다.
test쪽에 lifecycle이란 패키지를 만들어주고 그 안에 NetworkClient.java를 만들어줍시다.
그리고 구현을 해봅시다. 각각의 메서드들이 실행되면서 현재 어떤 메서드가 실행된것인지 확인하기 좋게 출력해줍시다.
생성자를 통해 만들어지자마자 connect()로 연결할 수 있게 해주었습니다.
추가적으로 LifeCycleConfig.java를 만들어 해당 클래스를 스프링에서 쓸 수 있도록 빈으로 만들어줍시다.
이제 한번 잘 작동되나 해볼까요?
lifecycle 패키지에 BeanLifeCycleTest.java를 만들어 테스트해줍시다.
실행 결과
아니 url이 다 null이 나오다니!!!! 사실 뻔한 일입니다.
LifeCycleConfig에서 보면 new를 해서 이미 생성자를 실행하게 됩니다. 그럼 생성자 호출 단계에서 url은 아직 설정되지 않았기에 null이 되겠죠? 그리고 생성자 안에 있는 connect()도 url 주입을 못 받은 다음 실행되어서 null이고, call도 그렇습니다.
이쯤되면 슬슬 어떤순서로 스프링이 작업을 진행하는지 헷갈리실겁니다. 스프링 빈의 이벤트 라이프사이클입니다.
스프링 컨테이너 생성 💨 스프링 빈 생성 💨 의존관계 주입 💨 초기화 콜백 💨 사용 💨 소멸전 콜백 💨 스프링 종료
저희는 여기서 초기화 콜백, 소멸전 콜백으로 해당 부분에 작업을 시키면서 위와 같은 문제를 해결해보려 합니다.
초기화, 소멸 메서드 지정
초기화와 소멸할 때 사용할 메서드를 저희가 만든 메서드들 중에서 직접 지정할 수 있습니다. 저희는 connect, disconnect였죠? 한번 해봅시다.
우선 생성자에서 connect()와 call() 같이 시작하자마자 할 작업들을 지워줍시다.
그 후 init()이라는 아예 초기화 콜백 단계에 진행할 작업들을 넣은 메서드를 만들고, close()라는 소멸전 콜백 단계에 진행할 작업들을 넣은 메서드를 만들어줍시다.
그 후 LifeCycleConfig에서 @Bean부분에 initMethod, destroyMethod를 추가해줍시다.
그리고 동일한 테스트를 돌려봅시다.
실행 결과
new를 통해 생성자가 실행될 때는 url이 null이지만 의존관계 주입 단계에서 setUrl이 먼저 진행이 되고 그 이후 생성자 콜백이 진행되면서 connect()와 call()에서 url이 잘 나오고 있는 것을 확인하실 수 있습니다.
그리고 ac.close()를 해서 스프링 컨테이너를 종료하며 자동으로 소멸자 기능도 실행되는 것도 확인하실 수 있습니다.
@PostConstruct와 @PreDestroy
얘들은 설정 클래스에서 설정을 해 주는게 아니어서 LifeCycleConfig를 원래대로 돌려줍시다.
이 어노테이션은 바로 우리가 만든 NetworkClient에 직접 넣어주면 됩니다. 바로 보여드리겠습니다.
간단하죠? 설명이 크게 필요하진 않을 것 같습니다. 실행결과를 확인해봅시다.
실행 결과
같은 결과가 나오는 것을 확인하실 수 있습니다.
두 방법 중 어떤 걸 써야할까?
둘 다 쓰기 좋아보이는데 어떤걸 쓰면 좋을까요? 상황에 따라 다릅니다.
1. 외부에서 받은 클래스를 쓰는 경우
외부 클래스는 저희가 수정을 못하죠. 이 코드안에 @PostConstruct같은 어노테이션을 추가하지 못하니 저희가 설정할 설정 클래스에서 @Bean에 initMethod, destroyMethod를 넣어주는 방법이 수월할것입니다.
2. 내가 만든 클래스를 쓰는 경우
내가 만든 클래스는 중간에 어노테이션 자유롭게 넣을 수 있겠죠? @Bean에 메서드 이름을 string으로 넣어주면 컴파일이 잡지 못하는 에러가 나올 수도 있기 때문에 @PostConstruct, @PreDestroy를 사용해줍시다.
마치며
이제 슬슬 스프링의 기본 기능을 배워보는 과정이 끝이 다가오고 있습니다!
그렇다고 아예 끝은 아니긴 하죠. MVC패턴에 대해서도 배우면서 API도 만들어서 진정한 개발자로 거듭나봅시다!!!