armeria icon indicating copy to clipboard operation
armeria copied to clipboard

Automatically create armeria's dependency when missing

Open jrhee17 opened this issue 3 years ago • 1 comments

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:

  1. Define an annotation (e.g. @CreateIfMissing)
  2. Add the custom annotation to armeria classes which may be injected
@CreateIfMissing
class ProtobufRequestConverterFunction {
}
  1. In BuiltInDependencyInjector, check for the annotation @CreateIfMissing and 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

jrhee17 avatar Nov 08 '22 06:11 jrhee17

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.

trustin avatar Nov 21 '23 09:11 trustin