- 자바코드로 스프링빈을 등록할땐 ,각각의 컨트롤러, 레포지토리, 서비스 등등에 @Controller, @Repository, @Service라고 적어주기
- 이 @로한것이 컴포넌트 스캔
- @Controller, @Repository, @Service 이것들다 들어가보면 컴포넌트와 다 연결되어있음
- 이것을 진행하면 스프링이 다 객체를 생성해서 스프링 컨테이너에 스프링 빈으로 등록시킨다.
- @ 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 //생성자에 Autowired라고 적혀있으면 스프링이 스프링 컨테이너안에 있는 memberService를 가져다가 연결시켜줌
//단 저 memberService는 @Service로 인해 스프링빈으로 등록되어있어야한다.
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
}
- 생성자에 있는 @Autowired는 스프링이 스프링 컨테이너안에 있는 스프링빈을 생성자의 인수로 넣어준다.
- 즉 @는 스프링이 (스프링 컨테이너에서) 접근할때 인식할 수 있게해줌
- 스프링 빈의 등록은 스프링을 실행시키는 SpringApplication이 있는 디렉토리부터 하위까지 있는것들을 뒤진다. 즉 그 상위는 의미가없음(실행하는 녀석 상위는 스캔이 불가능하다.)
- 스프링빈을 등록할때는 유일하게 하나만 등록 (helloController는 이거하나, memberService는 이서비스하나 —> 중복을 방지하고, 그 하나로 공유 >> 메모리절약 & 하나에만 접근 ) (싱글톤)
- 근데 지이이인짜 특수한 케이스에 설정으로 중복으로 등록할 수 있게함.
자바코드로 스프링 빈 등록하기
- 회원 서비스와 회원 리포지토리의 @Service, @Repository, @Autowired 애노테이션을 제거하고 진행.
- hello/hellospring 파일에 SpringConfig만들기 - 스프링 설정 파일(서버 실행하는) 있는곳에 만들기
package hello.hellospring;
import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
import hello.hellospring.service.MemberService;
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();
}
}
- 컨트롤러의 경우 어처피 처음부터 스프링이 관리하는거라 컴포넌트 스캔으로 올림(따로 설정하는게 아님)
- 장단점 ( 컴포넌트스캔 vs 자바코드로 직접 스프링 빈 설정)
- 자바코드 설정은 내가 원하는 디비메모리로 바로 바꿔치기 가능 (컴포넌트 스캔은 바꿔줘야할 코드가 많다)
- 컴포넌트 스캔은 대신 간편
- DI (dependant injection)
- 필드주입 ⇒ 생성자로 따로 넣는것이 아닌 선언부에 바로 autowired 애노테이션추가
- setter주입⇒ 퍼블릭으로 멤버를 선언해야해서 문제가 많음 하지말기
- 생성자 주입 ⇒ 우리가 해왔던것 - 이렇게 하자
- 실무에선 주로 정형화된 컨트롤러 , 서비스, 리포지토리같은 코드는 컴포넌트 스캔을 사용
- 정형화되지 않거나 상황에따라 구현클래스를 변경해야 하면 설정을 통해 스프링빈으로 등록
- @Autowired 를 통한 DI는 스프링이 관리하는 객체에서만 동작. 스프링 빈으로 등록하지 않은 내가 직접 생성한 객체에서는 동작하지않는다.