Study/Java

Spring ApplicationContext에서 GenericType 기준으로 bean 호출하기

Bluesky_ 2024. 3. 6. 00:33
반응형

다음과 같은 interface를 구현한

@FunctionalInterface
public interface ServiceSupplier<T> {

    T findOne(SomeParameter someParameter);

}

@FunctionalInterface
public interface ServiceListSupplier<T> {

    List<T> findList(SomeParameter someParameter);

}

다음과 같은 service가 있다고 가정해 보자.

@Service
public class SomeService implements ServiceSupplier<SomeObject>, ServiceListSupplier<SomeObject> {

    @Override
    public SomeObject findOne(SomeParameter someParameter) {
        // ... 구현 생략
    }

    @Override
    public List<SomeObject> findList(SomeParameter someParameter) {
        // ... 구현 생략
    }

}

하나의 service만 만들어서 사용하는 경우 직접 호출해서 사용하니 크게 필요하지 않지만 이러한 형태로 구현한 수많은 Service를 만들고 이를 전달받은 T 에 따라 호출하여 사용하고 싶은 경우 구현된 interface의 GenericType이 등록된 Bean을 호출하는 기준이 된다.

@Service
public class SomeService2 implements ServiceSupplier<SomeObject2>, ServiceListSupplier<SomeObject2> {
    //... 내용 생략
}

@Service
public class SomeService3 implements ServiceSupplier<SomeObject3>, ServiceListSupplier<SomeObject3> {
    //... 내용 생략
}

@Service
public class SomeService4 implements ServiceSupplier<SomeObject4>, ServiceListSupplier<SomeObject4> {
    //... 내용 생략
}

// ... 많은 Service bean 구현

Spring은 4.0 버전 이후 ApplicationContext에서 원하는 class의 GenericType의 bean을 호출하기 위해 ResolvableType 을 제공하고 있다.

이를 사용하여 applicationContext에서 해당 bean을 호출하는 방법은 다음과 같다.

ResolvableType type = ResolvableType.forClassWithGenerics(ServiceSupplier.class, SomeObject2.class);

List<ServiceSupplier<SomeObject2>> list = applicationContext.getBeanProvider(type).stream().toList();
반응형