의존성 주입(Dependency Injection, DI)은 객체들 간의 의존 관계를 외부에서 주입하는 프로그래밍 패턴이다. 이 패턴은 객체 내부에서 직접적으로 의존성을 생성하는 것이 아니라, 스프링 컨테이너에서 필요한 의존성을 제공함으로써 모듈 간의 결합도를 낮추고 유연성 및 재사용성을 높인다.
@Autowired는 스프링에서 의존성을 자동으로 주입할 때 사용하는 어노테이션이다. 스프링 컨테이너는 @Autowired가 붙은 필드, 생성자, 세터 메서드 등에 자동으로 관련 의존성(빈)을 주입한다.
@Autowired를 선언하여 의존성을 주입한다.import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class PostService {
// 필드에 @Autowired 직접 선언
@Autowired
private PostMapper postMapper;
}
@Autowired를 선언하여 의존성을 주입한다.@Autowired를 선언함으로써 의존성을 주입한다. 스프링 4.3 이후로는 생성자가 하나인 경우 @Autowired 생략 가능.@RequiredArgsConstructor를 사용하므로 써 생성자를 자동생성 하여 주입할 수도 있다.import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class PostService {
private PostMapper postMapper;
@Autowired
puvlic PostService(PostMapper postMapper){
this.postMapper = postMapper;
}
}
@RequiredArgsConstructor는 Lombok 라이브러리의 어노테이션으로, final이나 @NonNull 필드에 대한 생성자를 자동으로 생성한다. 이 어노테이션을 사용하면 필요한 의존성만을 포함하는 생성자를 자동으로 만들어주므로, 생성자 주입 방식에서 코드를 더욱 간결하게 만들 수 있다.
순환 참조란 두개 이상의 클래스가 서로 직접적이거나 간접적으로 참조하는 상황을 말한다.
의존성 주입을 하는 환경에서 문제가 될 수 있다.
public class ClassA {
private ClassB classB;
// ClassA의 생성자 또는 세터에서 ClassB의 인스턴스를 주입받음
public ClassA(ClassB classB) {
this.classB = classB;
}
}
public class ClassB {
private ClassA classA;
// ClassB의 생성자 또는 세터에서 ClassA의 인스턴스를 주입받음
public ClassB(ClassA classA) {
this.classA = classA;
}
}
ClassA는 ClassB의 인스턴스를 필요로 하며, ClassB 역시 ClassA의 인스턴스를 필요로 한다. 이러한 구조는 서로가 서로를 필요로 하는 순환 참조가 발생하게 된다.
순환 참조는 코드의 이해와 유지보수를 어렵게 만들 수 있다. 클래스간 의존성이 복잡해지고 코드를 추적하기 어려워 지기 때문이다.