[java] Guice의 바인딩(Binding)과 프로바이더(Provider)

Guice는 구글에서 개발한 Java 기반의 의존성 주입(Dependency Injection) 프레임워크입니다. Guice를 사용하면 객체 간의 의존성을 관리하고 코드를 더 모듈화하고 테스트하기 쉽게 만들 수 있습니다. 이를 위해 Guice는 바인딩(Binding)과 프로바이더(Provider)라는 개념을 제공합니다.

바인딩(Binding)

바인딩은 Guice에서 객체와 그 객체에 대한 의존성을 매핑하는 과정입니다. Guice를 사용하면 객체를 직접 생성하는 대신, Guice의 바인딩 기능을 이용하여 객체의 생성 및 의존성을 지정할 수 있습니다. 바인딩을 정의하는 방법은 다음과 같습니다.

기본적인 바인딩

bind(Service.class).to(ServiceImpl.class);

위의 예시에서 Service라는 인터페이스를 ServiceImpl이라는 구현체에 바인딩하였습니다. 이렇게 바인딩을 정의하면 Guice가 Service를 요청하는 곳에서 ServiceImpl을 반환하게 됩니다.

바인딩 주석

bind(DataSource.class).annotatedWith(Database.class).to(MySQLDataSource.class);

위의 예시에서 Database라는 주석을 사용하여 DataSource 인터페이스를 MySQLDataSource 구현체에 바인딩하였습니다. 이렇게 함으로써 Database 주석이 있는 경우에만 해당 바인딩이 적용되게 할 수 있습니다.

바인딩 인스턴스 생성

bind(Service.class).toInstance(new ServiceImpl());

위의 예시에서는 ServiceImpl의 인스턴스를 바인딩으로 지정하였습니다. 이렇게 함으로써 Guice는 항상 동일한 인스턴스를 반환하게 됩니다.

프로바이더(Provider)

프로바이더는 Guice에서 객체의 생성을 담당하는 인터페이스입니다. 프로바이더를 사용하면 객체의 생성 로직을 커스터마이징할 수 있습니다. 프로바이더는 javax.inject.Provider 인터페이스를 구현해야 합니다. 프로바이더를 사용하는 방법은 다음과 같습니다.

public class MyServiceProvider implements Provider<Service> {
    public Service get() {
        return new ServiceImpl();
    }
}

bind(Service.class).toProvider(MyServiceProvider.class);

위의 예시에서는 MyServiceProvider라는 클래스가 Provider<Service> 인터페이스를 구현하고, get() 메서드를 오버라이딩하여 원하는 인스턴스를 생성하도록 정의하였습니다. Service를 요청하는 곳에서는 해당 프로바이더의 get() 메서드가 호출되어 새로운 ServiceImpl 인스턴스를 반환하게 됩니다.

결론

Guice의 바인딩과 프로바이더는 객체 간의 의존성을 관리하고 유연하게 변경할 수 있도록 도와주는 기능입니다. 바인딩을 사용하면 객체와 의존성을 매핑하고, 프로바이더를 사용하면 객체의 생성 로직을 커스터마이징할 수 있습니다. 이를 통해 코드의 모듈화와 테스트 용이성을 향상시킬 수 있습니다.

참고 자료: