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();