Automatically create armeria's dependency when missing
Assume we have the following service with a custom dependencyInjector set via Server.builder().dependencyInjector(...)
class MyAnnotatedService {
@Get("/")
@RequestConverter(ProtobufRequestConverterFunction.class)
public HttpResponse foo(...) {...}
}
In this case, armeria is unable to find the appropriate dependency because ProtobufRequestConverterFunction is not registered in BuiltInDependencyInjector.
Unless the user manually registers the dependency manually in his/her custom dependencyInjector, the server would refuse to start.
We probably want to ensure that at least dependencies provided by armeria are always found by doing something like the following:
- Define an annotation (e.g.
@CreateIfMissing) - Add the custom annotation to armeria classes which may be injected
@CreateIfMissing
class ProtobufRequestConverterFunction {
}
- In
BuiltInDependencyInjector, check for the annotation@CreateIfMissingand generate a singleton if applicable.
if (type.hasAnnotation(CreateIfMissing.class)) {
return createSingleton(type);
}
https://github.com/line/armeria/blob/c4ebc7b3a42df17029641caf5f291c31b104e74b/core/src/main/java/com/linecorp/armeria/internal/common/BuiltInDependencyInjector.java#L44-L55
BuiltInDependencyInjector could discover them via Java SPI. Java SPI also uses the default constructor for instantiating the provider, so we could simply define a tag interface and list the types in META-INF/services/....
However, because Java SPI eagerly instantiates the providers, we might want to implement a lazy version of the same mechanism, so that the component being injected is instantiated when it's injected, rather than when the injector is instantiated.