minghxx.blog
  • [Spring] 스프링 입문 4) 스프링 빈과 의존관계
    2023년 10월 14일 16시 37분 15초에 업로드 된 글입니다.
    작성자: 민발자
    728x90

    스프링 입문 - 스프링 부트 웹 MVC, DB 접근 기술 

    Session 4 스프링 빈과 의존관계

    1. 컴포넌트 스캔과 자동 의존관계 설정

    멤버 컨트롤러가 멤버 서비스를 통해 회원가입, 데이터 조회 가능함 멤버 컨트롤러가 멤버 서비스를 의존한다 

    스프링이 시작될 때 스프링 컨테이너가 생성되고 @Controller 객체를 생성해(= 스프링 빈) 스프링 컨테이너에서 관리

    초록색 원이 스프링 빈

    1) 회원 컨트롤러에 의존관계 추가

    @Controller
    public class MemberController {
    	private final MemberService memberService;
    
    	@Autowired
    	public MemberController(MemberService memberService) {
    		this.memberService = memberService;
    	}
    	// memberService는 순수 자바코드기 때문에 스프링이 관리하는 빈이 아니다. 
    	// -> @Service 어노테이션을 붙여 스프링이 관리하게 만들자
    }

    @Autowired 스프링이 스프링 컨테이너에서 연관된 객체를 찾아서 주입해준다(=DI 의존성 주입)

    memberService는 아직 스프링 빈으로 등록되어있지 않아 오류가 발생한다. ▶ @Service 어노테이션으로 스프링 빈으로 등록해 스프링이 관리할 수 있게 선언

    메모리 리포지토리도 @Repository 어노테이션 선언해 스프링 빈으로 등록하고 @Autowired으로 연결해 서로 의존관계를 설정해준다

    2) 컴포넌트 스캔과 자동 의존 관계 설정

    @Component 애노테이션이 있으면 스프링 빈으로 자동 등록 (= 컴포넌트 스캔)

    @Controller, @Service, @Repository 등 @Component 애노테이션 포함되어있어 스프링이 시작될 때 객체를 하나씩 생성해 컨테이너에서 관리를 한다

    @Autowired는 스프링 빈들 관계를 연결해준다

     

    ▶ 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때 싱글톤 등록

    스프링 빈이면 모두 같은 인스턴스고 이걸 공유해서 사용한다.

     


    2. 자바 코드로 직접 스프링 빈 등록하기

    1) springConfig

    멤버 서비스와 멤버 리포지토리에 @Service, @Repository, @Autowired를 제거 후 사용

    @Configuration
    public class SpringConfig {
    	@Bean
    	public MemberService memberService() {
    		return new MemberService(memberRepository());
    	}
    	@Bean
    	public MemberRepository memberRepository() {
    		return new MemoryMemberRepository();
    	}
    }

    @Bean 어노테이션으로 빈으로 직접 등록

     

    ▶ DI 의존성 주입 3가지 방법

    필드 주입, setter 주입, 생성자 주입

    생성자 주입을 권장함(현재 코드)

    // 필드 주입
    @Autowired private MemberService memberService;
    
    // setter 주입
    @Autowired
    public void setMemberService(MemberService memberService) {
       this.memberService = memberService;
    }
    // public이기때문에 변경이 가능, 의존관계가 실행중 동적으로 변하는 경우는 거의 없으므로 권장하지 않음
    
    // 생성자 주입
    @Autowired
    public MemberController(MemberService memberService) {
    	this.memberService = memberService;
    }

     

    ▶ 상황에 따라 구현 클래스를 변경해야하면 설정을 통해 스프링 빈으로 등록

    실무에서는 정형화된 컨트롤러, 서비스, 리포지토이 같은 코드는 컴포넌트 스캔을 사용

     

     @Autowired를 통한 DI는 스프링이 관리하는 객체에만 동작

    내가 직접 생성한 객체(스프링 빈이 아닌 객체)에서는 동작하지 않는다

    728x90
    댓글