SpringBoot @Configuration中注入Bean

背景

场景是我在拦截器中加入一个鉴权的模块,有些地址某些用户是可以访问的,有些地址某些用户是不可以访问的,我们的拦截器是通过MVC配置中添加的,而配置我们用的是@Configuration进行标识的,而工具类(Bean)是通过@Component进行标识的。

故障

注入的工具类空指针

Caused by: java.lang.NullPointerException: Cannot invoke "top.zunmx.demo.configure.utils.PermissionUtils.can_access(String)" because "this.permissionUtils" is null
at top.zunmx.demo.configure.Interceptor.preHandle(Interceptor.java:23) ~[classes/:na]
at org.springframework.web.servlet.HandlerExecutionChain.applyPreHandle(HandlerExecutionChain.java:146) ~[spring-webmvc-6.1.2.jar:6.1.2]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1084) ~[spring-webmvc-6.1.2.jar:6.1.2]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.1.2.jar:6.1.2]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.1.2.jar:6.1.2]
... 36 common frames omitted

相关代码

拦截器

package top.zunmx.demo.configure;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import top.zunmx.demo.utils.PermissionUtils;

import java.util.logging.Level;
import java.util.logging.Logger;

public class Interceptor implements HandlerInterceptor {
    @Autowired
    private PermissionUtils permissionUtils;
    Logger logger = Logger.getLogger("Interceptor");

    public Interceptor() {
        logger.log(Level.INFO, "拦截器创建" + this);
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        logger.log(Level.INFO, "当前访问:" + request.getMethod() + "-->" + request.getRequestURI());
        boolean b = permissionUtils.can_access(request.getRequestURI());
        if(b){
            response.getWriter().print( request.getMethod() + "-->" + request.getRequestURI());
            return false; // 为了屏蔽error页(DEMO)
        }else{
            response.getWriter().print("ACCESS DENIED");
            return false;
        }
    }
}

MVC配置

package top.zunmx.demo.configure;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

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

鉴权工具类

package top.zunmx.demo.utils;

import org.springframework.stereotype.Component;

import java.util.logging.Level;
import java.util.logging.Logger;

@Component
public class PermissionUtils {

    Logger logger = Logger.getLogger("Interceptor");

    public PermissionUtils() {
        logger.log(Level.INFO, "授权工具类创建" + this);
    }

    /**
     * 是否可以访问?
     *
     * @param path
     * @return
     */
    public boolean can_access(String path) {
        return !path.equals("/admin");

    }

    /**
     * 设置权限
     *
     * @param path
     * @param ok
     * @return
     */
    public boolean set_permission(String path, boolean ok) {
        return true;

    }
}

解决方案

  1. 去掉鉴权工具类的@Component注解
  2. 在WebMvcConfig修改为以下代码

    ```
    @Bean
    public PermissionUtils getPermissionUtils(){
    return new PermissionUtils();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new Interceptor(getPermissionUtils()));
    }
    

    `` 3. 拦截器去掉@Autowired,以构造方法形式注入(终于明白为什么@Autowired`会有黄色波浪线了)

    ```
    private PermissionUtils permissionUtils;
    Logger logger = Logger.getLogger("Interceptor");

    public Interceptor(PermissionUtils permissionUtils) {
        this.permissionUtils = permissionUtils;
        logger.log(Level.INFO, "拦截器创建" + this);
    }
    

    ```

demo
image.png

注意

一定要取消掉鉴权工具类的@Component注解,否则可能会创建多个对象
如果不去掉的话,会是这个样子的。
image.png

示例下载

src.zip

评论 0

还没有评论,来说点什么吧。

提交后需要审核才会公开。