-
인프런 스프링 입문 06 / 스프링 빈 등록 2 가지스프링&스프링부트 2022. 12. 4. 15:45
스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
스프링 빈과 의존관계
- 스프링 빈을 등록하는 2가지 방법
> 컴포넌트 스캔과 자동 의존관계 설정
> 컴포넌트 스캔 원리 : @Component 애노테이션이 있으면 스프링 빈으로 자동 등록
> 자바 코드로 직접 스프링 빈 등록하기
1. 컴포넌트 스캔과 자동 의존관계 설정
- 회원 컨트롤러에 의존관계 추가
package hello.hellospring.controller; import hello.hellospring.service.MemberService; import org.springframework.stereotype.Controller; @Controller public class MemberController { private final MemberService memberService = new MemberService(); } }
- controller 생성 > 스프링 컨터이너에 controller 생성
- MemberController 제외한 다른 controller에서도 MemberService를 사용
- MemberService에는 특별한 기능이 없기 때문에 new 객체 생성해서 사용하는 것은 별로
- 스프링 컨테이너에 등록하고 계속 사용하는 것이 낫다 > @Autowired 사용 (연결 역할)
package hello.hellospring.controller; import hello.hellospring.service.MemberService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @Controller public class MemberController { private final MemberService memberService; @Autowired public MemberController(MemberService memberService) { this.memberService = memberService; } }
- MemberController에서 오류 발생 :
Consider defining a bean of type 'hello.hellospring.service.MemberService' in your configuration.
> MemberService는 순수한 java class이기 때문에 스프링이 알아볼 수 있는 방법이 없음
> MemberService에 @Service 어노테이션 추가
> MemoryRepository에 @Repository 어노테이션 추가
- @Autowired
> MemberController가 생성될 때 스프링 컨테이너에 등록되어있는 MemberService에 객체를 넣어준다
> 객체 의존관계를 외부에서 넣어주는 것 : DI (Dependency Injection, 의존관계 주입)
@Service public class MemberService { private final MemberRepository memberRepository; @Autowired public MemberService(MemberRepository memberRepository) { this.memberRepository = memberRepository; } //회원 가입 public long join(Member member) { validateDuplicateMember(member); memberRepository.save(member); return member.getId(); } }
- @Autowired
> MemberService 객체 생성 시점에 스프링 컨테이너에서 해당 스프링 빈을 찾아서 주입
> MemoryMemberRepository (구현체)를 service에 주입
> controller - service - repository 모두 연결 완료
- 스프링 빈 등록 이미지
- 참고:
스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록 (유일하게 하나만 등록해서 공유)
따라서 같은 스프링 빈이면 모두 같은 인스턴스다. 설정으로 싱글톤이 아니게 설정할 수 있지만, 특별한 경우를 제외하면 대부분 싱글톤을 사용한다.
싱글톤 패턴?
- 객체의 인스턴스가 오직 1개만 생성되는 패턴
> 장점 1. 메모리 : 최초 한 번의 new 연산자를 통해 고정된 메모리 영역을 사용하기 때문에 해당 객체에 접근할 때 메모리 낭비를 방지할 수 있고 속도도 빠르다
> 장점2. 데이터 공유가 쉬움 : 싱글톤 인스턴스가 전역으로 사용되는 인스턴스이기 때문에 다른 클래스의 인스턴스들이 접근하여 사용하기 쉽다
> 단점1. 싱글톤 패턴을 구현하는 코드 자체가 많이 필요
> 단점2. 테스트하기 어려움
>> 싱글톤 패턴은 단독으로 사용하면 객체지향에 위반되는 경우가 많다.
>> 스프링 컨테이너와 같은 프레임 워크의 도움을 받으면 문제점들을 보완하면서 장점만을 이용 가능
>> 스프링 빈은 컨테이너의 도움을 받아 싱글톤 스콥으로 관리되고 있다
2. 자바 코드로 직접 스트링 빈 등록하기
package hello.hellospring.service; import hello.hellospring.repository.MemberRepository; import hello.hellospring.repository.MemoryMemberRepository; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class SpringConfig { @Bean public MemberService memberService() { return new MemberService(memberRepository()); } @Bean public MemberRepository memberRepository() { return new MemoryMemberRepository(); } }
- DI 3가지
> 의존관계가 실행 중에 동적으로 변하는 경우는 거의 없으므로 생성자 주입을 권장한다.
1. 필드 주입
public class MemberController { @Autowired private MemberService memberService; }
2. setter 주입
public class MemberController { private MemberService memberService; @Autowired public void setMemberService(MemberService meberService) { this.memberService = memberService; } }
3. 생성자 주입
public class MemberController { private final MemberService memberService; @Autowired public MemberController(MemberService memberService) { this.memberService = memberService; } }
- 참고:
실무에서는 주로 정형화된 컨트롤러, 서비스, 리포지토리 같은 코드는 컴포넌트 스캔을 사용한다. 그리고 정형화 되지 않거나, 상황에 따라 구현 클래스를 변경해야 하면 설정을 통해 스프링 빈으로 등록한다.
- 주의: @Autowired 를 통한 DI는 helloController , memberService 등과 같이 스프링이 관리하는 객체에서만 동작한다. 스프링 빈으로 등록하지 않고 내가 직접 생성한 객체에서는 동작하지 않는다.
* 자바 기초를 다시 공부해야겠다는 생각이 든다...
( 참고 )
https://tecoble.techcourse.co.kr/post/2020-11-07-singleton/
728x90'스프링&스프링부트' 카테고리의 다른 글
인프런 스프링 입문 08 / 스프링 DB 접근, H2, JDBC (0) 2022.12.06 인프런 스프링 입문 07 / 회원관리 예제 (0) 2022.12.06 인프런 스프링 입문 05 / 회원 관리 예제, junit 테스트하는 방법 (0) 2022.12.04 JSON이란? JSON 기초 정리 (1) 2022.12.03 인프런 스프링 입문 03 / 정적 콘텐츠, MVC (0) 2022.12.02