Search code examples
javaspringspring-bootredisjedis

NullPointerException for Springboot @Autowired component in interceptor


I have a component that's the main job is to return a Jedis instance, and it looks like the following:

@Component
public class JedisConfig {

    private Jedis jedis;

    public JedisConfig() {
        jedis = new Jedis("localhost", 6379);
    }

    public Jedis getJedis() {return jedis;}
}

I then use the Jedis instance to do some stuff in my interceptor's preHandler:

public class AuthInterceptor implements HandlerInterceptor {

    @Autowired
    private JedisConfig jc;

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Jedis jedis = jc.getJedis();
        
        // do some other stuff with jedis below
    }
}

But I get a NullPointerException when calling jc.getJedis() and I don't understand why it's happening.

On a related note, I did pretty much the exact same thing in a unit test and it runs fine:

@Autowired
private JedisConfig jc;

@Test
public void testJedis(){
    Jedis jedis = jc.getJedis();

    jedis.set("user", "role");
    assertThat(jedis.get("user"),is("role"));
}

Here's How I added the interceptor to the registry:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AuthInterceptor())
                .addPathPatterns("/user/roleChange");
    }
}

If anyone knows how to fix this please let me know. Thank you so much!


Solution

  • The AuthInterceptor is not a Spring bean, and the JedisConfig is not autowired and is null. As long as the interceptor is used in the @Configuration class, you can perform autowiring there and encapsulating the JedisConfig interceptor.

    @RequiredArgsConstructor // either use Lombok or write the constructor by yourself
    public class AuthInterceptor implements HandlerInterceptor {
    
        private final JedisConfig jc;
    }
    
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Autowired
        private JedisConfig jc;
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new AuthInterceptor(jc))
                    .addPathPatterns("/user/roleChange");
        }
    }
    

    Alternatively, you can treat the AuthInterceptor as a component and autowire it in the WebConfig class:

    @Component
    public class AuthInterceptor implements HandlerInterceptor {
    
        @Autowired
        private JedisConfig jc;
    
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            Jedis jedis = jc.getJedis();
            
            ...
        }
    }
    
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Autowire
        private AuthInterceptor authInterceptor;
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(authInterceptor)
                    .addPathPatterns("/user/roleChange");
        }
    }