인프런 커뮤니티 질문&답변

lsj59285님의 프로필 이미지
lsj59285

작성한 질문수

스프링 핵심 원리 - 기본편

빈 등록 초기화, 소멸 메서드

질문입니다.

작성

·

731

5

1. InitializingBean와 DisposableBean

"개발자가 코드를 고칠 수 없는 외부 라이브러리에는 적용할 수 없다."라고 설명하셨습니다. 외부 라이브러리의 코드를 제가 직접 고칠 수 없는 건 알겠는데, 그렇기 때문에 해당 메소드를 적용할 수 없는 이유를 좀 더 상세하게 알려주시면 감사하겠습니다.

2. initMethod와 destroyMethod

"코드가 아니라 설정 정보를 사용하기 때문에 코드를 고칠 수 없는 외부 라이브러리에도 해당 메소드를 사용할 수 있다."라고 설명하셨습니다. 여기서 해당 기능이 설정 정보를 사용한다는 말의 뜻과 그렇기 때문에 외부 라이브러리에서 사용할 수 있는 이유를 좀 더 상세하게 알려주시면 감사하겠습니다.

답변 4

11

먼저 외부 라이브러리가 어떤 형태의 파일이며 그걸 어떻게 사용하는지에 대해 아시면 이해하는데 도움되실 것 같네요.

외부 라이브러리는 보통 class파일로 구성되어 있습니다. 이를 사용자에게 배포할 때는 일반적으로 java파일이 아닌 컴파일한 뒤 생성된 결과물인 class파일을 jar로 패키징하여 배포합니다.

여기서 문제가 발생합니다.

class파일은 바이트코드로 구성되어있기 때문에 JVM이 읽기 편한 파일이지 개발자가 읽으면서 수정하기 편한 파일이 아닙니다.

그러므로 개발자가 class파일을 수정하기 어렵다는 것입니다. (어려운 것이지 못하는 것은 아닙니다.)

.

예를 들어보겠습니다.

A라는 외부 라이브러리가 있으며 당연히 외부 라이브러리 특성상 모든 파일은 컴파일된 class파일입니다.

이 라이브러리에는 NetworkClient라는 클래스가 있습니다.

이 클래스에 aInit, aDestroy라는 메서드가 존재합니다.

개발자인 우리는 이 클래스를 스프링 빈으로 수동 등록하였습니다.

그런데 스프링이 로딩되고 종료될 때 자동으로 aInit(), aDestroy()가 실행되게 만드려고 합니다.

스프링 초창기에 지원했던 InitializingBean, DisposableBean 인터페이스를 사용하고자 합니다.

위 2가지 인터페이스를 NetworkClient라는 클래스에 적용하여 afterPropertiesSet, destroy를 구현하려고 했습니다.

그런데 NetworkClient는 java파일이 아니라 바이트코드로 구성된 class파일이어서 코드를 변경하기 어려운 것입니다.

그래서 NetworkClient 클래스를 직접 수정하는 방법(인터페이스를 구현하는 것) 대신 수동으로 빈을 등록할 때 @Bean의 속성인 init, destroy를 사용하는 방법을 택했습니다.

이미 NetworkClient 클래스에서 제공하는 메서드인 aInit, aDestroy가 존재하므로 init, destroy 속성의 값으로 aInit, aDestroy를 넣어 스프링이 시작하고 종료될 때 aInit, aDestroy가 실행되게 했습니다.

.

위 시나리오가 강의에서 말씀하시고자 한 부분입니다.

이해하시는데 도움이 되셨으면 하네요.

6

안녕하세요. lsj59285님, 공식 서포터즈 David입니다.

.
1. 외부 라이브러리를 수정할 수 없기 때문에 InitializingBean, DisposableBean을 외부 라이브러리에 적용할 수 없습니다.

코드를 수정할 수 없으니 해당 인터페이스들을 적용할 수 없고

해당 인터페이스를 적용할 수 없으니 메서드(afterPropertiesSet, destroy)를 구현할 수 없고

메서드가 구현되지 않으니 스프링이 로드될 때 afterPropertiesSet, destroy가 호출되지 않습니다.

구현되지 않은 메서드를 호출할 수는 없는 것이죠.

그래서 외부 라이브러리에 InitializingBean, DisposableBean을 적용할 수 없는 것입니다.

만약 난 무조건 InitializingBean, DisposableBean을 사용해서 초기화와 종료를 하겠다면 외부 라이브러리의 Wrapper Class를 만들고 해당 Wrapper Class에 InitializingBean, DisposableBean을 구현하여 Wrapper Class를 빈으로 등록할 수도 있을 것 같습니다. 저라면 그냥 @Bean의 속성(init, destory)을 사용하겠습니다.

2. "코드가 아니라 설정 정보를 사용한다"에서 코드는 외부 라이브러리 코드를 말합니다. 만약 외부 라이브러리가 수정 가능한 형태(.java)가 아니라 .class 형태라면 우리가 할 수 있는 것은 외부 라이브러리의 API를 호출하는 것 밖에 없습니다.

설정 정보는 Bean을 수동등록하는 Configuration파일을 말합니다.

@Bean()의 init, destory 속성에 외부 라이브러리의 초기화, 종료 메서드를 지정하는 것만으로도 스프링이 시작되고 종료될 때 @Bean의 init, destory 속성에 지정된 메서드가 실행됩니다.

그래서 (외부 라이브러리의) 코드가 아니라 설정 정보(Bean을 수동 등록하는 Configuration파일)를 사용한다 라고 말씀하신 겁니다.

위의 맥락에 따라 외부라이브러리 코드 수정 없이 초기화 메서드, 종료 메서드만 지정해주면 되기 때문에 코드 수정이 필요한 InitializingBean, DisposableBean과 달리 외부 라이브러리를 사용할 수 있다고 표현하신 겁니다.

.
감사합니다.

2

와.. 진짜 이것과 관련하여 질문할려고 했는데 명쾌히 해결됐습니다

1

lsj59285님의 프로필 이미지
lsj59285
질문자

그런데 강의에 보면 InitializingBean, DisposableBean 사용할 때,  

@Override만 하고, @Bean 객체의 코드는 일절 수정하지 않던데요?

이게 외부 라이브러리 코드를 수정하지 않는 거 아닌가요?

해당 단원의 설명이 다른 단원에 비해 좀 부실한 거 같습니다...ㅠㅠ

lsj59285님의 프로필 이미지
lsj59285

작성한 질문수

질문하기