만든 클래스(컨트롤러, 레포지토리 등)를 스프링에서 사용하려면 스프링빈에 등록을 해주어야 한다 (의존성 주입)
스프링 빈을 등록하는 2가지 방법
- 컴포넌트 스캔과 자동 의존관계 설정
- 자바 코드로 직접 스프링 빈 설정하기
컴포넌트 스캔
-
@Component 어노테이션이 있으면 스프링 빈으로 자동 등록된다.
-
@Controller, @Service, @Repository 는 @Component를 포함하고 있기 때문에 스프링 빈으로 자동 등록된다.
-
생성자에 @Autowired를 사용하면 객체 생성 시점에 스프링 컨테이너에서 해당 스프링 빈을 찾아서 주입한다. (생성자가 1개만 있으면 @Autowired는 생략 가능)
- 의존성을 주입은 생성자가 아니더라도 setter 방식이나 필드에 직접 주입하는 방식으로도 가능하지만 필드는 확장성이 떨어지고 setter의 경우 불필요하게 다른 곳에서 호출될 수도 있기에 생성자에서 주입하는걸 권장한다.
스프링은 스프링 컨테이너에 스프링 빈을 등록할 때 기본적으로 싱글톤으로 등록한다. 따라서 같은 스프링 빈이면 모두 같은 인스턴스이다. 상황에 따라 설정을 통해 싱글톤이 아니게 설정할 수 있지만 특별한 경우를 제외하면 대부분 싱글톤을 사용한다고 한다.
자바 코드로 직접 스프링 빈 등록하기
위에서 설명했던 어노테이션(@Service, @Repository, @Autowired)을 제거한다.
@Bean 어노테이션을 작성하고 직접 생성자를 만들어 대입해준다.
각각의 장단점
컴포넌트 스캔
- 장점
- 어노테이션 하나로 의존성 주입과 빈 등록을 자동화할 수 있어 코드가 간결하고 직관적이다.
- 클래스마다 별도의 빈 등록 코드가 필요하지 않기 때문에 중복 코드가 줄어든다.
- 클래스에 변경이 발생하거나 새로운 클래스가 추가되더라도 스프링이 자동으로 관리해 주므로 유지 보수성이 좋다.
- 단점
- 특정 조건이나 복잡한 로직에 따라 빈을 등록하거나 설정할 때는 제한적이다.
- 자동 주입 시 어노테이션 설정 실수로 인해 컴파일 타임이 아닌 런타임에 오류가 발생할 가능성이 있다.
자바 코드
- 장점
- 빈을 명시적으로 등록하므로 어떤 빈이 생성되고 주입되는지 명확하게 알 수 있다.
- 의존성 주입을 더 세밀하게 관리할 수 있다.
- 테스트 코드 작성 시 특정 빈만 교체하거나 테스트용 빈을 등록하는 것이 쉬워 단위테스트에 유리하다.
- 단점
- 클래스마다 직접 빈을 등록하는 코드가 필요하므로 코드가 길어지고 복잡해질 수 있다.
- 모든 빈을 명시적으로 등록하는 경우 자동화된 스프링의 기능을 활용하지 못할 수 있다.
결론
주로 정형화된 컨트롤러, 서비스, 레포지토리 같은 코드는 컴포넌트 스캔을 사용
정형화 되지 않거나 상황에 따라 구현 클래스를 변경해야 한다면 직접 등록하는 방식으로 !