Why can’t your interceptor inject Java beans?

Time:2020-11-24

1、 How to implement interceptor

In the spring boot project,InterceptorIt is often used for login verification, logging and other operations. Interceptors are provided by spring, so they can be injected as beans and managed by the IOC container. The implementation of interceptor is very simple, which mainly consists of the following two steps:

  1. Implementation of custom interceptor classHandlerInterceptorInterface
  2. Implementation of custom MVC classWebMvcConfigurerInterface, add custom interceptor class

The implementation code is as follows:

custom interceptor LoginInterceptor

public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String token = request.getHeader("token");
        if(StringUtils.isEmpty(token)){
             ...
            return false;
        }
        return true;
    }
}

To configure a custom Interceptor:

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                //Blocked requests
                .addPathPatterns("/**")
                //Requests without blocking
                .excludePathPatterns("/login");
    }
}

The main function of this interceptor is to intercept all access requests and verify thetokenWhether it is effective, whentokenOnly after successful verification can we access our business interface. At this point, you need to provide a verificationtokenThe valid interface is verified in the interceptortokenSince the interceptor is provided by spring, it’s easy to think of using it@ComponentAnnotations annotate the interceptor as a bean. Then use the@AutowiredThe annotation will validatetokenClass is injected into the interceptor for validation.

The code after modification is as follows:

Verify token interface class:

@Component
public class TokenUtil {
    /**
     *Verify that the token is valid
     */
    public boolean checkToken(String token){
        ...
    }
}

The modified interceptor code is as follows:

@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    private TokenUtil tokenUtil;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if(!tokenUtil.checkToken(token)){
            ...
            return false;
        }
        return true;
    }
}

When calling the interface, we found that tokenutil was not injected in! It is clear that the code is OK, why can’t it be injected normallyTokenUtilWhat about it?

Take a closer look at our custom configuration classesWebConfigurationWhen adding interceptors, usenew LoginInterceptor()If you want the interceptor to take effect, you must configure the interceptor into the webmvc configuration class, which is our customWebConfigurationClass. Now when adding an interceptor, a new interceptor is added, that is to say, the interceptor is not managed to the IOC container, so spring’s bean object cannot be introduced

2、 How to host interceptors to IOC containers

The idea to solve the problem is also very simple, that is, the interceptor is also managed to the IOC container, so that the objects in the container can be injected into each other. There are three ways to deal with the above problems.

2.1 inWebConfigurationInjection interceptor

The interceptor code remains unchanged and is used on the interceptor@ComponentAt the same timeWebConfigurationUse in@AutowiredAnnotations inject interceptors.

Interceptor Code:

@Component
public class LoginInterceptor implements HandlerInterceptor {
}

Configuration class code:

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    @Autowired
    private LoginInterceptor loginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor);
    }
}

2.2 inWebConfigurationAnnotate interceptors as beans

Interceptors do not need to be added@ComponentNote, inWebConfigurationClass@BeanAnnotations annotate interceptors as beans.

Interceptor Code:

public class LoginInterceptor implements HandlerInterceptor {
}

Configuration class code:

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    @Bean
    public LoginInterceptor loginInterceptor(){
        return new LoginInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor( loginInterceptor());
    }
}

2.3 processing by constructor

The idea is toWebConfigurationClass to inject the required validationtokenThen, when initializing the interceptor, the business class is brought into the interceptor through the constructor, so that the interceptor does not need to be annotated as a spring bean object.

Interceptor Code:

public class LoginInterceptor implements HandlerInterceptor {

    private TokenUtil tokenUtil;

    public LoginInterceptor(TokenUtil tokenUtil) {
        this.tokenUtil = tokenUtil;
    }
}

Configuration class code:

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    @Autowired
    private TokenUtil tokenUtil;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor(tokenUtil));
    }
}

3、 Summary

The interceptor code on the Internet is basically configured through a new interceptor. At this time, other beans cannot be injected. A lot of people add directly to the interceptor@ComponentAnnotations make it a bean object. This is a wrong approach. What we need to make sure is thatAn interceptor of MVC bean is added to the class of MVCIn other words, we need to annotate the interceptor as a bean and add the bean to the webmvc configuration class.

4、 Pay attention, don’t get lost

If you think the article is good, welcomefollowgive the thumbs-upCollectionThank you very much for your support.

If there is a problem with the article, please don’t be stingy with the writing. Welcome to leave a message and point out that I will check and revise it in time.

If you want to see more things, you can search on wechatJava journey“And pay attention to it. “Java journeyAt present, we have sorted out various middleware use tutorials and various Java related interview questions.