spring boot

spring boot 05 [ 스프링 빈과 의존관계 ]

지니엠 2023. 12. 10. 12:29

 

 

 

DI 의존성 주입에 대해 알아보자!

생성자에 @Autowired를 추가하면 스프링이 연관된 객를 스프링 컨테이에서 찾아서 넣어준다.

이렇게 객체 의존관계를 외부에서 넣어주는것을 DI(Dipendency Injection), 의존성 주입이라고 한다

 

 

controller단에서 의존성 주입을 해주자

@Autowired
public MemberController(MemberService memberService) {
    this.memberService = memberService;
}

근데 이렇게 해주고 실행하면 오류가 발생한다.

memberService가 빈으로 등록되어있지 않아서, 쉽게 말해 controller랑 service단이 연결이 안되는것이다

 

그럼 이제 service단에서 빈으로 등록을 해보자.

 

빈을 등록할때는 크게 두가지 방법이 있다

① 컴포넌트 스캔을통해 자동으로 등록하는 방법

② 자바코드로 직접 설정 파일에 등록하는 방법

 

[ Component 스캔으로 등록 ]

@Component 어노테이션이 있다면 스프링 빈으로 등록할 수 있다.

>> @Controller, @Service, @Repository 모두 @Component를 포함하고 있기 때문에

어노테이션을 쓰면 자동으로 빈등록이 되는것이다.

 

Service 단에서 

@Service
public class MemberService {

    private final MemberRepository memberRepository;

    public MemberService(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    } 
}

@Service 어노테이션만 주입해주면 되는것!

 

 

helloController는 스프링이 제공하는 컨트롤러여서 스프링 빈으로 자동 등록된다.

즉 @Controller 가 있으면 자동 등록된다는것.

 

아무대나 @Component가 있어도 되나? >> 기본적으로는 안된다

기본실행할때 HelloSpringApp 파일 하위파일에서 spring이 찾아서 bean으로 등록하기때문에

다른 파일에있으면 등록이 안된다.

 

싱글톤 : 유일하게 하나만 등록해서 공유

 

 

spring framework에서도 이방법을 썼기때문에 이렇게 계속 쓰지않을까

 

 

 

[ 자바코드로 등록하는 방법 ]

 

상위 폴더에 SpringConfig 파일을 만들고

@Configuration
public class SpringConfig {
    @Bean
    public MemberService memberService(){
        return new MemberService(memberRepository());
    }// memberservice를 빈으로 등록해달라는것을 알아차리고 등록해줌

    @Bean
    public MemberRepository memberRepository() {

        return new MemoryMemberRepository();
    }

위의 코드를 작성해준다.

 

XML로 설정하는 방식도 있지만 최근에는 잘 사용하지 않는다.

 

DI에는 필드 주입, setter 주입, 생성자 주입 이렇게 3가지 방법이 있다.

의존관계가 실행중에 동적으로 변하는 경우는 거의 없으므로 생성자 주입을 권장한다

 

생성자 주입방법

public MemberService(MemberRepository memberRepository) {
    this.memberRepository = memberRepository;
}

 

필드주입방법

@Autowired private final MemberService memberService;

>> 필드주입 방법은 중간에 변경하고싶을때 방법이 없다.

 

setter 주입방법

@Autowired
public void setMemberService(MemberService memberService) {
    this.memberService = memberService;
}

>> 누군가 memberController을 호출했을때 이게 퍼블릭으로 열려있어야 한다.

퍼블릭으로 열려있으면 호출하지 않아야할때도 호출될수있고, 그러다가 중간에 잘못 건들수가 있기 때문에 문제가 발생할 수 있다.

 

생성자는 한번만 딱 조립해놓고 끝나기 때문에, 그 다음 변경을 못하도록 막아둘 수 있어서 (사실 쓰다보면 변경할 일도 없다)

결론적으로 생성자 주입방법을 쓰는것이 제일 좋다.

 

 

 

 

 

한개의 강의를 정말 여러번 돌려보고 이해했는데, 

구조적인 이미지를 머리속에서 떠올릴 수 있는게 중요한것같다