Java 如何注入拦截器?
我已经配置了一个安全拦截器,该拦截器应该注入用户会话对象(这是一个单例对象),我在这里尝试了:Java 如何注入拦截器?,java,dependency-injection,guice,Java,Dependency Injection,Guice,我已经配置了一个安全拦截器,该拦截器应该注入用户会话对象(这是一个单例对象),我在这里尝试了: public DependencyInjection extends AbstractModule{ //Class that has AccessLevel Annoation bind(InterfaceA.class).to(ImplA.class); bind(UserPersistor.class).to(UserPersistorImpl.class); //My sess
public DependencyInjection extends AbstractModule{
//Class that has AccessLevel Annoation
bind(InterfaceA.class).to(ImplA.class);
bind(UserPersistor.class).to(UserPersistorImpl.class);
//My session that I wish to inject
bind(UserSession.class).to(UserSessionHandler.class);
bindInterceptor(Matchers.any(), Matchers.annotatedWith(AccessLevel.class),
new SecurityInterceptor(getProvider(UserSession.class)));
}
这里是我的UserSessionHandler:
@Singleton
public class UserSessionHandler implements UserSession {
private UserLevel userLevel = UserLevel.DEFAULT;
private final UserPersistor userPersistor;
@Inject
public UserSessionHandler(UserPersistor userPersistor) {
this.userPersistor = userPersistor;
}
@Override
public boolean loginUser(String userName, String password) {
Benutzer user = userPersistor.getUserByName(userName);
if (user == null) {
return false;
} else {
if (user.getKennwort().equals(password)) {
userLevel = UserLevel.valueOf(user.getRolleId().getBezeichnung().toUpperCase());
return true;
} else {
return false;
}
}
}
@Override
public boolean logoutUser() {
userLevel = UserLevel.DEFAULT;
return true;
}
@Override
public UserLevel getUserLevel() {
return userLevel;
}
}
下面是SecurityInterceptor当前的外观:
@Singleton
public class SecurityInterceptor implements MethodInterceptor {
private final Provider<UserSession> session;
@Inject
public SecurityInterceptor(Provider<UserSession> session){
this.session = session;
}
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
AccessLevel[] acessRoles = invocation.getMethod().getAnnotationsByType(AccessLevel.class);
List<UserLevel> allowedRoles = new ArrayList<>();
for(AccessLevel accessRole: acessRoles){
allowedRoles.add(accessRole.value());
}
//Make sure that User has one of the allowed Access-Levels
if (!allowedRoles.contains(session.get().getUserLevel())) {
throw new InvalidAccessException("No Access allowed with userlevel" + session.get().getUserLevel());
}
return invocation.proceed();
}
}
然而,我不想自己创建一个实例,而是希望guice创建一次。我该怎么做,或者我现在做错了什么
编辑:我的主要问题是usersession似乎与生成的会话不同。这里有一个简单的例子:
Injector injector = Guice.createInjector(new DependencyInjection());
UserSession session = injector.createInstance(UserSession.class);
InterfaceA methodCaller = injector.createInstance(InterfaceA.class);
if(session.loginUser("a","b")){
System.out.println(session.getUserLevel().toString()); //Returns Admin
}
methodCaller.callMethodWithAnnotation();
现在,当我在拦截器中检查session.getUserLevel时,我得到“Default”
EDIT2:我的最终目标是在我的拦截器和我使用UserSession的任何地方都有相同的session实例当我在类中使用调用login函数的提供程序而不仅仅是DI UserSession时,它会以某种方式起作用。谁能给我解释一下区别是什么?在我看来,这并不重要,因为它是guice的单例。为什么SecurityInterceptor是@singleton?我猜,当它是单例时,如果您只@injectusersession,您将始终得到相同的实例注入。当你使用Provider时,它会注入不同的实例。就像但是Provider不应该也尊重@singleton一样吗?目前,我有一个具有@InjectUserSession的提供程序,它被用来代替注入。这是一个好的设计还是一个坏的设计?您是否使用了任何示例来实现您的代码?很难理解您的代码。我使用了以下示例:@Justas但是他似乎使用了属性注入,我更喜欢基于构造函数(因为我所有的其他人也都是基于构造函数的),当我在类中使用调用登录函数的提供程序而不是仅使用DI UserSession时,它会以某种方式工作。谁能给我解释一下区别是什么?在我看来,这并不重要,因为它是guice的单例。为什么SecurityInterceptor是@singleton?我猜,当它是单例时,如果您只@injectusersession,您将始终得到相同的实例注入。当你使用Provider时,它会注入不同的实例。就像但是Provider不应该也尊重@singleton一样吗?目前,我有一个具有@InjectUserSession的提供程序,它被用来代替注入。这是一个好的设计还是一个坏的设计?您是否使用了任何示例来实现您的代码?很难理解您的代码。我使用了以下示例:@Justas,但他似乎使用了属性注入,我更喜欢基于构造函数的方法(因为我所有的其他方法也基于构造函数)
Injector injector = Guice.createInjector(new DependencyInjection());
UserSession session = injector.createInstance(UserSession.class);
InterfaceA methodCaller = injector.createInstance(InterfaceA.class);
if(session.loginUser("a","b")){
System.out.println(session.getUserLevel().toString()); //Returns Admin
}
methodCaller.callMethodWithAnnotation();