-
Notifications
You must be signed in to change notification settings - Fork 38.8k
Description
I'm on a team migrating a relatively large and complex Java application to Kotlin and Spring. It's not feasible to top-down refactor the entire app to Kotlin and dependency injection all at once. To facilitate incremental migration, we capture the ApplicationContext
to a static field on startup. From there it can accessed throughout the application. Legacy code can use the ApplicationContext
as a service locator via its BeanFactory
and ListableBeanFactory
methods to access the Spring-ified parts of the application. As the refactoring to DI proceeds, the direct ApplicationContext
references are pulled up the call stack until the top-level @Configuration
is reached.
We tend to prefer disambiguating beans by type, so T BeanFactory.getBean(Class<T>)
is the most commonly used locator method. The problem is, generic types aren't supported. There's ObjectProvider<T> BeanFactory.getBeanProvider(ResolvableType requiredType)
, but its use involves a bit of boilerplate:
ParameterizedTypeReference<List<List<String>>> parameterizedTypeReference =
new ParameterizedTypeReference<>() { };
ResolvableType resolvableType =
ResolvableType.forType(parameterizedTypeReference);
ObjectProvider<List<List<String>>> objectProvider =
applicationContext.getBeanProvider(resolvableType);
List<List<String>> listOfListOfString =
objectProvider.getObject();
This can be wrapped up into a utility, but it would be nice if ParameterizedTypeReference
overloads of the getBean
methods were already available, for example:
List<List<String>> listOfListOfString =
applicationContext.getBean(new ParameterizedTypeReference<List<List<String>>>() { });
They would also streamline the Kotlin getBean
extension implementations with their reified type parameters (see #31439).
I noticed more discussion of ParameterizedTypeReference
vs. ResolvableType
in #20195. I tend to agree with the comments that the super type token approach of ParameterizedTypeReference
makes for the more convenient public API.
I realize using the application context as a service locator is not the primary design intent for the framework, but I'm hoping the migration use case warrants consideration of ParameterizedTypeReference
overloads. Presumably they could be added as interface default methods for backwards compatibility.