개발자 취업준비/springboot

의존성주입

naspeciallist 2024. 10. 26. 00:55

강의를 들으면서 개념정리를 위주로 하겠다.

이미 프로젝트를 2개 진행 한뒤 개념이 부족한거 같아서 다시 정리하는 거 이기 때문에 따로 코드는 적지 않고 개념 위주로 정리를 하였다.

 

@Autowired : 필드주입 

처음에는 aplication context에서 비활성화로 나두었다가 Atuowired를 통해서 활성화 시켜서 주입을 한다.

@component를 통해서 빈으로 등록할 객체를 정하고 aplicationcontext에서 관리를 하게 된다.

 

메소드 안에 지역변수 안에서는 Autowired를 사용할 수 없다.

 

즉 정리하면 의존성주입의 동작원리는

1. @component를 통해 aplicationcontext에서 관리 할 객체 설정

2. 비활성화되어있는 객체를 Autowired를 통해 활성화 시켜 준다.

 

단점: 굉장히 편하게 주입할 수 있으나 순환참조(무한 루프) 시 오류가 발생하지 않기 때문에 StackOverFlow 발생

 

객체지향프로그램의 특성상 어느 한곳에서 변경 할 시 연쇄 작용이 발생 할 수 있음

@Autowired를 사용할 시 final을 붙일 수 없기 때문에 다른 곳에서 변형 가능

 

따라서 이 단점들을 보안하기 위해서
생성자를 통해서 주입 할 수 있다.

 

private final Computer computer;

public Coding(Computer computer) {
 this.computer = computer;
 }

 

선언과 동시에 초기화를 하게 된다. 

그러면 선언을 할 때 문제가 발생 할 수 있기 때문에 순환참조가 발생을 할때 오류가 발생하게 된다.

순환 참조 시 컴파일러 인지 가능 , 오류 발생

메모리에 할당되면서 최기값으로 주입되므로 초기값에 문제 발생시 할당도 되지 않기 때문이다.

초기화 생성자를 사용하면 해당 객체에 final을 사용 할 수 있다. 다른 곳에서 변형 불가능

의존성 주입이 되지 않으면 객체가 생성되지 않으므로 NPE를 방어

 

@RequiredArgsContructor

롬복에 기능으로 final이나 @NonNull이 붙은 것만 초기화를 해줌 

 

 

@AllArgsContructor : 전체 필드 초기화

@NoArgsContructor : 기본 생성자 초기화

 

 Qualifier

@Autowired를 통해 객체를 주입 할 때 같은 타입의 객체가 여러 개 있다면 구분 할 수 없다는 문제점이 발생하게 된다.

 

@Qualifier를 통해서 구분자를 정 할 수 있다.

 

public interface Computer {
    public int getScreenWidth();
}



@Component
public class Desktop implements Computer{

    @Override
    public int getScreenWidth() {
        return 2180;
    }
}



@Component
public class Laptop implements Computer{

    @Override
    public int getScreenWidth() {
        return 1920;
    }
}

 

 

@SpringBootTest @Slf4j
public class ComputerTests {

    @Autowired
    Computer computer;

    @Test
    public void computerTest(){
        log.info(computer.toString());
    }
}

 

만약 이렇게 테스트 코드를 짜고 실행을 할 시 아래 사진과 같은 오류가 발생하게 된다.

빈이 여러개라 어떤 빈을 사용 할 줄 몰라서 뜨는 오류이다.

 

public interface Computer {
    public int getScreenWidth();
}



@Component @Qualifier("desktop") @Primary
public class Desktop implements Computer{

    @Override
    public int getScreenWidth() {
        return 2180;
    }
}



@Component @Qualifier("laptop")
public class Laptop implements Computer{

    @Override
    public int getScreenWidth() {
        return 1920;
    }
}

 

@SpringBootTest @Slf4j
public class ComputerTests {
    @Autowired @Qualifier("desktop")
    Computer desktop;

    @Autowired @Qualifier("laptop")
    Computer laptop;

    @Autowired
    Computer computer;

    @Test
    public void computerTest(){
        log.info(desktop.toString());
        log.info(laptop.toString());
        log.info(computer.toString());
    }
}

이렇게 @Qualifier 를 이용하여 빈이 중복되었을 때 구분자를 지어 줄 수 있다.