강의를 들으면서 개념정리를 위주로 하겠다.
이미 프로젝트를 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 를 이용하여 빈이 중복되었을 때 구분자를 지어 줄 수 있다.
'개발자 취업준비 > springboot' 카테고리의 다른 글
관점 지향 프로그래밍(AOP) (1) | 2025.01.21 |
---|---|
제어의 역전(IoC)와 의존성 주입(DI) (1) | 2025.01.19 |
라이브러리와 프레임워크 (0) | 2025.01.15 |
서버와 클라이언트 (0) | 2025.01.13 |
스프링부트 프로젝트 생성 및 초기설정 git연결 (0) | 2025.01.12 |