Search code examples
javaspringguice

Spring define a request scoped bean that has access to the request object


I am migrating a Java application that uses guice and guice-servlet libraries for DI to Spring(both as a web framework and DI).

I have the following code with GUICE that i need to migrate:

import com.google.inject.servlet.RequestScoped;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.servlet.http.HttpServletRequest;

@RequestScoped
public class CurrentUserProvider implements Provider<User> {

  private static final String CURRENT_USER_HEADER = "x-current-user";

  @Inject
  private Provider<HttpServletRequest> requestProvider;

  @Override
  public User get() {
    return new User(requestProvider.get().getHeader(CURRENT_USER_HEADER));
  }
}

And in my Guice module i have something like: bind(User.class).toProvider(CurrentUserProvider.class); which basically enables me to inject a User object with the current user anywhere in my app.

Basically the idea is to have a request scoped bean which takes info from the header of the request. I saw that in Spring there is a similar annotation as in Guice for request scoping.

What i don't understand is: How to create a bean that has access to the headers of the current request(even if it's a Spring object)? Limitations: I want to be able to do this with Java annotations(not with XML) Bonus: I it can somehow work with the existing provider it would be great.


Solution

  • You have forgotten @Component to ask Spring to consider that class a bean. Then you need @Autowired not @Inject to ask for HttpServletRequest to be injected. According to documentation all spring beans of Request scope can ask for HttpServletRequest to be injected.

    As for provider you don't even need it to read that request. You can read it directly from HttpServletRequest

    @Component
    @RequestScoped
    public class CurrentUserProvider implements Provider<User> {
    
      private static final String CURRENT_USER_HEADER = "x-current-user";
    
      @Autowired
      private HttpServletRequest httpServletRequest;
    
      @Override
      public User get() {
      return new User(httpServletRequest.getHeader(CURRENT_USER_HEADER));
       }
    
    }