I'd like to use HK2 DI to automatically inject a new instance of a class depending on the user logged on my Jersey API.
User is logged with a class AuthenticationFilter and I can find get it into @Context SecurityContext in all my endpoints.
Thing is I have a DAO class that needs info about the user to be instanciated. It's just the schema on which I should execute the queries on the database.
So the constructor of my Dao is like this:
public UserDao(String schemaCompte) {
super(schemaCompte);
}
What seems to be the solution is to use a Factory to instanciate my Dao with HK2 so I tried creating one like that:
public class UserDaoFactory implements Factory<UserDao> {
@Context SecurityContext securityContext;
@Override
public UserDao provide() {
User userPrincipal = (User) securityContext.getUserPrincipal();
return new UserDao(userPrincipal.getCode());
}
@Override
public void dispose(UserDao userDao) {
}
}
And the binding goes like this:
bindFactory(UserDaoFactory.class).to(UserDao.class)
And implementation:
@Inject
public UserSvc(UserDao userDao) {
...
}
But this factory is called too soon in the lifecycle of my application and SecurityContext is still empty.
So as I understand it the solution for that to be executed at runtime would be to bind the Factory as a proxy like that:
bindFactory(UserDaoFactory.class).proxy(true).to(UserDao.class)
But when I do that I get a runtime exception:
java.lang.RuntimeException: java.lang.InstantiationException: com.metier.user.UserDao_$$_jvst5c_0
If anyone got an idea I've tried so many things and I'm completly out of luck
So, it turns out what I was missing was the annotation @PreMatching
in the provider I registered in my Jersey Api.
This annotation tells Jersey to execute this filter before everything else, even matching with the endpoint that was called.
So in this filter I just read my Token and it was available in the UserDaoFactory
where needed to inject the user account.
I made a small github repo to explain my point: https://github.com/m4nu56/jersey-hk2 and also a Medium article: https://medium.com/@mnu/jersey-injection-dependency-example-with-hk2-84ebfb7cb2d2
And In the end I didn't used the Factory since I didn't realize I can directly inject the user or the account in the constructor of my Dao.