의존성 주입(Dependency Injection)은 객체 간의 의존 관계를 느슨하게 만들기 위한 디자인 패턴.
의존성 주입은 객체가 직접 필요로 하는 의존 객체를 생성하는 대신, 의존 객체를 외부에서 주입해 사용하는 방식.
주로 생성자, setter, 필드 세 가지 방식으로 의존성 주입을 구현할 수 있다.
생성자를 통한 의존성 주입은 객체를 생성할 때 필요한 의존 객체를 생성자의 매개변수로 전달하는 방식.
public class Client {
private Service service;
public Client(Service service) {
this.service = service;
}
public void doSomething() {
service.execute();
}
}
public interface Service {
void execute();
}
public class ServiceImpl implements Service {
@Override
public void execute() {
// 서비스 실행 로직
}
}
// 사용 예시
Service service = new ServiceImpl();
Client client = new Client(service);
client.doSomething();
위의 예시에서 Client 클래스는 Service 인터페이스에 의존한다.
생성자에서 Service 객체를 받아 멤버변수인 service에 할당.
doSomething 메서드에서는 주입받은 service 객체의 execute 메서드를 호출해 작업 수행.
Service 인터페이스는 execute 메서드를 정의,
ServiceImpl 클래스는 이 인터페이스를 구현해 execute 메서드 구현
사용예시에서 ServiceImpl클래스의 객체를 생성해 Service 타입의 변수 service에 할당,
Client 객체를 생성시 생성자를 통해 service 객체 주입.
doSomething 메서드를 호출해 의존성 주입 통해 주입된 service객체의 execute 메서드 실행
-> 생성자 주입은 의존성의 불변성과 명시적인 의존성 표현을 강조해 코드의 안정성과 가독성을 높이는데 도움.
Setter 메서드를 통한 의존성 주입은 의존 객체를 설정하는 Setter 메서드를 통해 주입하는 방식.
public class Client {
private IService service;
public void setService(IService service) {
this.service = service;
}
public void doSomething() {
service.execute();
}
}
Client 클래스는 IService 인터페이스에 의존하며,
setService 메서드를 통해 의존 객체를 주입받는다.
doSomething 메서드에서는 주입받은 service 객체의 execute 메서드를 호출하여 작업 수행
public interface IService {
void execute();
}
IService 인터페이스는 execute 메서드를 정의하고 있다.
이 인터페이스를 구현하는 클래스가 주입.
public class ServiceImpl implements IService {
public void execute() {
// 서비스 실행 로직
}
}
ServiceImpl 클래스는 IService 인터페이스를 구현하고 있어 execute 메서드에서 실제 서비스 실행 로직 구현
// 사용 예시
IService service = new ServiceImpl();
Client client = new Client();
client.setService(service);
client.doSomething();
위의 예시에서의 ServiceImpl 클래스의 객체를 생성해 IService 타입의 변수 service에 할당.
Client 객체를 생성한 후, setService 메서드를 통해 service 객체를 주입한다.
마지막으로 doSomething 메서드를 호출하여 의존성을 주입을 통해 주입된 service 객체의 execute 메서드를 실행한다.
필드를 통한 의존성 주입은 의존 객체를 클래스의 필드로 선언하고, 외부에서 직접 주입하는 방식.
public class Client {
private IService service;
public void doSomething() {
service.execute();
}
}
public interface IService {
void execute();
}
public class ServiceImpl implements IService {
public void execute() {
// 서비스 실행 로직
}
}
위의 코드에서 Client 클래스는 IService 인터페이스에 의존하며,
service라는 필드를 가짐.
의존성 주입을 수행하기 위해 Client 클래스의 필드 service에 의존 객체를 주입할 수 있다.
IService service = new ServiceImpl();
Client client = new Client();
client.service = service;
client.doSomething();
위의 코드에서는 ServiceImpl 클래스의 객체를 생성하여 IService 타입의 변수 service 에 할당.
그리고 Client 객체의 Service 필드에 주입.
마지막으로 doSomething 메서드를 호출해 의존성 주입을 통해 주입된 service 객체의 execute 메서드를 실행.
필드를 통한 의존성 주입은 직접적으로 필드에 접근해 주입해,
일반적으로 생성자나 setter 메서드를 사용하는 것보다 더 느슨한 결합도를 가짐.
그러나 필드에 직접 접근해 캡슐화의 원칙에 위배할 수 있어 주의해야함.
스프링 핵심기능은 @Annotaion/XML/Groovy/자바 클래스 파일을 통해 객체를 생성 및 초기화
이렇게 생성되고 초기화된 객체를 Bean 객체라고 말한다.
우리는 레고처럼 여러개의 객체를 조합해 하나의 프로그램을 완성시킨다.
그럼 B객체에서 A객체의 기능(메서드)를 사용ㅎ아는 경우 우리는 어떻게 할 수 있을까?
의존성?
B클래스가 A클래스의 메서드를 호출할 때
이를 B클래스는 A클래스의 의존적이다.
의존성주입 방법
의존 객체를 전달 받는 방식 vs 의존 객체를 직접 생성 방식
spring에서는 Bean 객체를 IoC 컨테이너라는 곳에 저장해놓고 Bean객체에 의존하고 있는 객체에 전달.
이렇게하면 어떤점이 좋을까 ?
블로그 추천