class 的依赖注入,其构造函数需要有关登录 SecurityContext 的用户的信息
Dependency-Injection of a class with constructor that need info about the user logged in SecurityContext
我想使用 HK2 DI 自动注入 class 的新实例,具体取决于登录我的 Jersey API 的用户。
用户使用 class AuthenticationFilter 登录,我可以在我的所有端点中找到将其放入 @Context SecurityContext 中。
事情是我有一个 DAO class 需要有关要实例化的用户的信息。它只是我应该在其上执行数据库查询的架构。
所以我的Dao的构造函数是这样的:
public UserDao(String schemaCompte) {
super(schemaCompte);
}
解决方案似乎是使用工厂通过 HK2 实例化我的 Dao,所以我尝试创建一个这样的:
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) {
}
}
绑定是这样的:
bindFactory(UserDaoFactory.class).to(UserDao.class)
和实施:
@Inject
public UserSvc(UserDao userDao) {
...
}
但是这个工厂在我的应用程序的生命周期中调用得太早了,SecurityContext 仍然是空的。
据我所知,在运行时执行的解决方案是像这样将工厂绑定为代理:
bindFactory(UserDaoFactory.class).proxy(true).to(UserDao.class)
但是当我这样做时,我得到了一个运行时异常:
java.lang.RuntimeException: java.lang.InstantiationException: com.metier.user.UserDao_$$_jvst5c_0
如果有人知道我已经尝试了很多东西但我完全不走运
所以,事实证明我缺少的是我在 Jersey Api 中注册的提供商中的注释 @PreMatching
。
此注释告诉 Jersey 在执行其他所有操作之前执行此过滤器,甚至与调用的端点匹配。
所以在这个过滤器中,我刚刚读取了我的令牌,它在需要注入用户帐户的 UserDaoFactory
中可用。
我做了一个小 github 回购来解释我的观点:https://github.com/m4nu56/jersey-hk2 and also a Medium article: https://medium.com/@mnu/jersey-injection-dependency-example-with-hk2-84ebfb7cb2d2
最后我没有使用工厂,因为我没有意识到我可以直接在我的 Dao 的构造函数中注入用户或帐户。
我想使用 HK2 DI 自动注入 class 的新实例,具体取决于登录我的 Jersey API 的用户。
用户使用 class AuthenticationFilter 登录,我可以在我的所有端点中找到将其放入 @Context SecurityContext 中。
事情是我有一个 DAO class 需要有关要实例化的用户的信息。它只是我应该在其上执行数据库查询的架构。
所以我的Dao的构造函数是这样的:
public UserDao(String schemaCompte) {
super(schemaCompte);
}
解决方案似乎是使用工厂通过 HK2 实例化我的 Dao,所以我尝试创建一个这样的:
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) {
}
}
绑定是这样的:
bindFactory(UserDaoFactory.class).to(UserDao.class)
和实施:
@Inject
public UserSvc(UserDao userDao) {
...
}
但是这个工厂在我的应用程序的生命周期中调用得太早了,SecurityContext 仍然是空的。
据我所知,在运行时执行的解决方案是像这样将工厂绑定为代理:
bindFactory(UserDaoFactory.class).proxy(true).to(UserDao.class)
但是当我这样做时,我得到了一个运行时异常:
java.lang.RuntimeException: java.lang.InstantiationException: com.metier.user.UserDao_$$_jvst5c_0
如果有人知道我已经尝试了很多东西但我完全不走运
所以,事实证明我缺少的是我在 Jersey Api 中注册的提供商中的注释 @PreMatching
。
此注释告诉 Jersey 在执行其他所有操作之前执行此过滤器,甚至与调用的端点匹配。
所以在这个过滤器中,我刚刚读取了我的令牌,它在需要注入用户帐户的 UserDaoFactory
中可用。
我做了一个小 github 回购来解释我的观点:https://github.com/m4nu56/jersey-hk2 and also a Medium article: https://medium.com/@mnu/jersey-injection-dependency-example-with-hk2-84ebfb7cb2d2
最后我没有使用工厂,因为我没有意识到我可以直接在我的 Dao 的构造函数中注入用户或帐户。