Jersey 2.x Custom Injection Annotation With Attributes(Jersey 2.x 带有属性的自定义注入注解)
问题描述
I am in the process of migrating from DropWizard 0.7.1 to 0.8.1. This includes migrating from Jersey 1.x to 2.x. In my
implementation that uses Jersey 1.18.1, I had a MyProvider
(changed all class names for simplicity's sake) that implements InjectableProvider
. This
class would create MyInjectable
objects, containing the custom injection annotation, MyToken
. MyToken
contains various attributes
that are passed on and read by MyInjectable
. Lastly, in the Application
class I register a new instance of MyProvider
, as seen below.
I've done some research and can't seem to wrap my head around on how I'd recreate (or replace, I suppose) such a secenario in Jersey 2.x.
Here is the current, 1.18.1 implementation:
Yeah Jersey made the creation of custom injections a bit more complicated in 2.x. There are a few main components to custom injection you need to know about with Jersey 2.x
org.glassfish.hk2.api.Factory
- Creates injectable objects/servicesorg.glassfish.hk2.api.InjectionResolver
- Used to create injection points for your own annotations.org.glassfish.jersey.server.spi.internal.ValueFactoryProvider
- To provide parameter value injections.
You can read more about custom injection in Custom Injection and Lifecycle Management. One shortcoming of the documentation is the lack of explanation of how to inject parameter values. You could get away with simply implementing the InjectResolver
, and you would be able to inject into fields with your custom annotation, but in order to inject into method parameters, we need to ValueFactoryProvider
.
Luckily there are some abstract classes we can extend (which the documentation also fails to mention) that will make life a little easier. I has to scour the source code of the org.glassfish.jersey.server.internal.inject
package for a bit to try and figure it all out.
Here's a full example to help get you started.
Token
(injectable object)
@TokenParam
(our injection annotation)
TokenFactory
(implements Factory
per the first bullet point, but we just extend the AbstractContainerRequestValueFactory
. There we'll have access to the ContainerRequestContext
. Note, that all these HK2 components, we can inject other dependencies into them, for example the TokenAuthenticator
, which we will bind to HK2 later.
TokenParamInjectionResolver
(implements the InjectResolver
per bullet point two. I simply extend ParamInjectionResolver
. If your interested in what's going on under the hood, you can find the class in the source code I linked to)
TokenFactoryProvider
(implements the ValueFactoryProvider
per the third bullet point. I simply extend AbstractValueFactoryProvider
. Again, you can look at the source for the under the hood details)
TokenFeature
(Here we bind all the components seen above, even the TokenAuthentictor
, which I have left out, but if your usual Dropwizard Authenticator
. I also made use of a Feature
. I tend to do this to wrap components of a custom feature. This is also where you can decide all the scoping. Just note some components are required to be in Singleton
scope)
And finally simply register the feature
Now you should be able to inject the Token
with @TokenParam
, as well as your usual entity bodies (which would not be possible if we didn't implement the ValueFactoryProvider
UPDATE
It's kind of a half-@$$ example for your particular use case. A better approach would probably have a clone method in your Factory
class and create a new TokenFactory
with some parameters (maybe that you get from your annotation. For example, in the
TokenFactory` you can have something like
In the TokenFactoryProvider
ine createValueFactory
method, you then call the clone method
Or you could actually create the factory inside the method. you have options.
UPDATE 2
See Also
- jersey 2 context injection based upon HttpRequest without singleton
UPDATE 3
Starting Jersey 2.26, the dependency injection has changed. You will want to look at this post for example of how the code has changed in implementing this same injection.
这篇关于Jersey 2.x 带有属性的自定义注入注解的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!