객체간의 의존성을 줄이고 코드의 재사용성과 유지보수 쉽게할수 있게하는 디자인패턴입니다.
주로 사용하는 방식으로는 AutoWried를 사용한 수동주입과 생성자를 사용한 자동주입이 있는데
최근에는 생성자를 이용한 자동주입을 주로 사용합니다.
DI를 사용하면 자신이 필요로하는 의존성을 스스로 생성하는게 아니라 외부에서 주입받아 사용하게 됩니다.
예를들어 호텔클래스와 룸 클래스가 있을때 룸 클래스는 호텔클레스에 의존성이 생기게됩니다.
이때 DI를 사용하여 룸클래스에서 호텔클래스의 인스턴스를 매개변수로 사용하여 주입받으면
의존성을 제거하여 유지보수가 간결해집니다.
또한 테스트코드를 작성할때도 호텔대신 Mock객체를 사용하여 테스트할수 있게되므로 테스트코드 작성에도 용이해집니다.
필드주입 방식의경우 @Autowired를 붙여서 선언합니다
생성자 주입의경우 생성자를통해 주입합니다
이때, @RequiredArgsConstructor 어노테이션을 사용하여 코드를 간결하게 할수있습니다
기본적으로 인텔리제이에서는 @AutoWired를 사용하여 DI를 진행하려할때 경고메세지가 나오며 생성자 방식을 추천합니다
그 이유는 다음과같습니다
먼저 위와같은 세팅일때 bikeService를 생성하는것으로는 오류가나지않는다.
하지만 bikeService.move()의 주석을풀어 실행하게되면
이와같이 오류가 발생하게됩니다
이는 BikeService가 생성될때
빈에 등록되지않은 객체 bileService가 생성되었기때문입니다
때문에 bileService안에 CarService를 주입해야한다는 사실을 알수없는데
이때 null에대한 메소드요청을하기때문에 null pointer에러가 발생하게됩니다
생성자 주입시 final선언이 가능해지기때문에 추후 변경을 방지하여 객체의 불변성을 보장할수있습니다.
테스트코드를 작성할때 Mock를 이용해 작성하는 경우가 많은데, 생성자 주입일땐 원하는객체를 만들어 생성자에 넣기만하면 쉽게 테스트가 가능합니다