Spring boot的filter 不能注入redis的问题 解决

在Spring Boot中,由于filter的初始化顺序早于bean,导致filter内无法通过注解正常注入RedisUtil。解决方法是在配置类中使用@Bean注解创建并返回Filter实例,确保其在正确的时间被初始化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题

在filter实现类这里注入的redisUtil 但是 拿到的却是 null

public class SecurityFilter implements Filter {
 	@Autowired
	RedisUtil redisUtil; 

web应用启动的顺序是:listener->filter->servlet,先初始化listener,然后再来就filter的初始化,再接着才到我们的dispathServlet的初始化,因此,当我们需要在filter里注入一个注解的bean时,就会注入失败,因为filter初始化时,注解的bean还没初始化,没法注入。
所以需要创建filter的时候 需要@Bean初始化一下

然后返回查看注册Filter看下 发现 问题出现在 没有 在@Bean这样去创建返回对象

	@Bean
	public SecurityFilter securityFilter() {
		return new SecurityFilter();
	}

可以正常注入的Filter

注册Filter

@Configuration
public class FilterConfig {
	@Bean
	public FilterRegistrationBean FilterRegistrationBean2(){
		FilterRegistrationBean<Filter> filterFilterRegistrationBean = new FilterRegistrationBean<>();
		//将filter注入进去
		filterFilterRegistrationBean.setFilter(securityFilter());
		//需要过滤的网址
		filterFilterRegistrationBean.addUrlPatterns(
			"/OTApply/*");
	//设置filter的等级
	filterFilterRegistrationBean.setOrder(Ordered.LOWEST_PRECEDENCE);
	//设置filter的名字
	filterFilterRegistrationBean.setName("tokenFilter");
	
	return filterFilterRegistrationBean;
	}

	//注意上面	不能直接new 一个filter  一定要通过这种方式 来返回对象 要不然不能注入到spring boot里面
	@Bean
	public SecurityFilter securityFilter() {
		return new SecurityFilter();
	}
}

Filter实现类

@Slf4j
public class SecurityFilter implements Filter {
 	@Autowired
	RedisUtil redisUtil; 
 	@Override
 	public void init(FilterConfig filterConfig) throws ServletException {}

	@Override
 	public void destroy() {}
 	
 	@Override
 	public void doFilter(ServletRequest servletRequest,
 									ServletResponse servletResponse,
									FilterChain chain) throws IOException, ServletException {
 			
 			HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
			HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
 			String token = httpServletRequest.getHeader("token");
 			System.out.println(token+"从header那里获取token");
 			String requestURL = httpServletRequest.getRequestURL().toString();
 			String method = httpServletRequest.getMethod();
 			System.out.println(method);
 			System.out.println(requestURL+"requestURL");
 			String path = requestURL.substring(requestURL.lastIndexOf("/") + 1);
 			//如果token是空的就返回去 并告知登录后再进行操作
 			if (token == null || token.equals("null")) {
 				 error(httpServletResponse, HttpStatus.UNAUTHORIZED.value(), "请登陆后再进行操作");
				 return;
 			}
		 	UserVO userVO = null;
		 	try {
		 			userVO = (UserVO) redisUtil.get(token);
		 	}catch (Exception e) {}
		 
		 	if (null == userVO) {
		 			error(httpServletResponse, HttpStatus.UNAUTHORIZED.value(), "token失效");
		 		}
 			//每在这个网页上操作都会重置redis的过期时间
 			redisUtil.set(token, userVO, Constants.EXPIRE_TIME);
			//若上面运行都不出差错 就会继续执行下去
			chain.doFilter(servletRequest, servletResponse);
 }

			private void error(HttpServletResponse httpServletResponse, int status, String message) {
 				httpServletResponse.setContentType("application/json;charset=utf-8");
				httpServletResponse.setStatus(status);
				PrintWriter writer = null;
				try {
					writer = httpServletResponse.getWriter();
					writer.write(JsonUtil.toJsonString(Result.withMessage(message)));
				} catch (IOException e) {} finally {
					writer.close();
				}
 }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值