빈 등록과 관리

June·2022년 5월 25일
0

우테코

목록 보기
47/84

학습 배경

사실 지난 미션까지만해도 @Controller, @Service, @Repository를 제외하고는 직접 빈으로 뭔가를 등록해준 적이 없었다. 하지만 이번 미션을 하면서 내가 만든 클래스를 빈으로 등록해서 사용하면 좋을 것 같은 일이 생겼다.

FarePolicyImpl

FareService

마침 학습테스트에서 빈 등록 하는 방법에 대해 테스트해 볼 기회도 있어 찾아봤다.

빈과 컴포넌트 차이점

이 부분이 헷갈렸다. 실제로 '빈으로 등록했다', '컴포넌트로 등록했다' 등으로 많이 듣고 썼기 때문이다.

우선 명확히 해야하는 것은 스프링 IoC 컨테이너에서 관리하는 빈과 애노테이션 @Bean은 다르다.

스프링 공식 문서에서 빈의 정의는Srping IoC 컨테이너에 의해서 관리되고 어플리케이션에서 중요한 역할을 하는 객체다.

@Component를 사용하거나 @Bean을 사용하면 BeanDefinition의 인스턴스로서 Spring IoC 컨테이너에서 관리 대상이 되는 것이다.

@Bean vs @Component

그렇다면 @Bean@Component는 어떻게 다를까?

@Component 주석

클래스 레벨에 붙여서 auto-detection의 대상이 된다.

@Bean 주석

메서드에 붙여서 해당 메서드가 Spring container가 관리할 빈을 생성하는 것을 나타낸다.

만약 내가 작성한 코드가 아닌 외부 라이브러리를 사용한다고 생각해보자. 외부 라이브러리의 클래스에 내가 직접 @Component를 붙이지 못할 수도 있다. 이럴 때는 해당 클래스를 생성해서 반환하는 메서드에 @Bean을 붙여서 빈으로 등록할 수 있다.

컨테이너 설정

객체 관리 대상과 의존성 설정을 할 수 있는 세 가지 방법이 있다.

XML

UserRepository

UserService

/resources/application-config.xml

UserRepository가 있고 UserServiceUserRepository에 의존하고 있을 때 의존성 설정을 xml 파일에서 직접해주고 있다.

간단한 프로그램일 경우 각 클래스들의 의존성 설정을 이렇게 직접 해줄 수 있겠지만 프로젝트의 규모가 커지면 어려울 것 같다는 생각이 든다. 또한 직접 문자열로 관리를 하기 때문에 오타에도 취약할 것이다.

Java-based Configuration

각 메서드가 빈으로 등록할 객체를 생성해서 등록해주고 있다. authenticationPrincipalArgumentResolver()에서는 의존성 주입을 authService() 메서드를 이용해서 하고 있다.

참고로 @Bean@Configuration 클래스가 아닌 @Component나 심지어 일반 클래스에서도 사용될수는 있다. 이럴 경우 lite Bean mode라고 하며 위처럼 다른 @Bean 메서드를 참조할 수 없다.

여기서 clientDao() 메서드가 clientService1()에서도 호출되고 clientService2()에서도 호출되고 있다. clientDao() 메서드가 새로 객체를 생성해서 주니 각각 호출된 객체가 다르다고 생각할 수 있다. 하지만 스프링 컨테이너는 기본적으로 빈을 싱글톤으로 관리한다. 캐싱해서 만약 인스턴스가 존재하면 그걸 돌려준다.

공식 문서에 따르면 Java-based Configuration이 100% xml 방식을 대체하라고 있는 것은 아니라고 한다. xml에서 namespace 관리 같은 것은 여전히 유용한 방식이라고 한다.

Annotation-based Configuration

AuthService

AuthenticationPrincipalArgumentResolver

남은 궁금증

어떤 것을 빈으로 등록할지 말지가 사실 아직 명확하지 않다. 페어와 이야기를 나눴을 때 장단점에 대해 이야기 해보았다.

빈으로 가능한 등록하지 말자 의견: 도메인의 의존관계를 너무 스프링이 관리하게 하는 것은 좋지 않은 것 같다. 프레임워크 없어도 도메인은 돌아가야하지 않을까? 또 불필요하게 많이 빈으로 등록되어 관리되면 메모리 관리에도 좋지 않을 것 같다.

빈으로 등록해도 괜찮다 의견: 스프링이 해주지 않는다면 결국 조립기의 역할을 해주는 클래스를 작성해주어야 하고 그것도 개발자의 비용이다. 애초에 프레임워크를 사용하는 큰 이유 중 하나가 객체의 생성과 조립을 맡기는 것이 아닌가?

0개의 댓글