解决过滤器和拦截器里面注入redisTemplate 为null

博客主要讨论Spring中拦截器或过滤器直接注入IOC管理的普通bean为null的情况。指出过滤器可在init方法中从上下文获取bean,若要获取jar里的bean,如在过滤器中使用Redis,可采用构造器注入方式,拦截器同理。

关于spring中在拦截器或者过滤器中 直接注入由ioc管理的普通bean 为null的情况

过滤器可以在init方法中从上下文获取

public class TestFilter implements Filter {

    private TestService testService;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        ServletContext servletContext = filterConfig.getServletContext();
        WebApplicationContext cxt = WebApplicationContextUtils.getWebApplicationContext(servletContext);
        if (testService == null) {
            testService = (TestService) cxt.getBean("testService");
        }
    }

}

如果想获取jar里面带的bean  比如在过滤器里面想使用redis的话  采用上述方式是不行的  ,我们采用构造器注入的方式

 

先注入redis

@Configuration
public class TestConfig {

    @Bean
    public JedisConnectionFactory getJedisConnectionFactory(){
        JedisConnectionFactory connectionFactory = new JedisConnectionFactory();
        connectionFactory.setHostName("127.0.0.1");
        connectionFactory.setPort(6379);
        return connectionFactory;
    }

    @Bean
    public StringRedisTemplate getRedisTemplate(){
        StringRedisTemplate redisTemplate = new StringRedisTemplate();
        redisTemplate.setConnectionFactory(getJedisConnectionFactory());
        return redisTemplate;
    }

    @Bean
    public FilterRegistrationBean getFilterRegistrationBean(){
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        //通过构造器传入StringRedisTemplate 
        registrationBean.setFilter(new TestFilter(getRedisTemplate()));
        registrationBean.setUrlPatterns(new ArrayList<>(Arrays.asList("/*")));
        return registrationBean
    }
}
public class TestFilter implements Filter {

    private TestService testService;

    private StringRedisTemplate redisTemplate;

    //通过构造器实例化redisTemplate 就可以直接使用了
    public TestFilter(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        ServletContext servletContext = filterConfig.getServletContext();
        WebApplicationContext cxt = WebApplicationContextUtils.getWebApplicationContext(servletContext);
        if (testService == null) {
            testService = (TestService) cxt.getBean("testService");
        }
    }
}

2.拦截器也是同样的道理  可以通过构造器注入

@Configuration
public class TestConfig extends WebMvcConfigurationSupport {

    @Bean
    public JedisConnectionFactory getJedisConnectionFactory() {
        JedisConnectionFactory connectionFactory = new JedisConnectionFactory();
        connectionFactory.setHostName("127.0.0.1");
        connectionFactory.setPort(6379);
        return connectionFactory;
    }

    @Bean
    public StringRedisTemplate getRedisTemplate() {
        StringRedisTemplate redisTemplate = new StringRedisTemplate();
        redisTemplate.setConnectionFactory(getJedisConnectionFactory());
        return redisTemplate;
    }

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        //通过构造器注入
        registry.addInterceptor(new TestInterceptor(getRedisTemplate())).addPathPatterns("/**").excludePathPatterns("/emp/toLogin", "/emp/login", "/js/**", "/css/**", "/images/**");
        super.addInterceptors(registry);
    }
}
public class TestInterceptor implements HandlerInterceptor {

    private StringRedisTemplate stringRedisTemplate;

    //通过构造注入
    public TestInterceptor(StringRedisTemplate stringRedisTemplate){
        this.stringRedisTemplate=stringRedisTemplate;
    }

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }
}

 

<think> 我们被要求回答:在Spring Boot中配置使用拦截器的方法。 根据引用内容,我们可以总结如下步骤: 1. 创建自定义拦截器:实现HandlerInterceptor接口,并重写其方法(preHandle, postHandle, afterCompletion)。 2. 注册拦截器:通过配置类(实现WebMvcConfigurer接口)并重写addInterceptors方法,将自定义拦截器注册到Spring Boot应用中。 此外,引用中还提到了一些高级应用最佳实践,如多拦截器的执行顺序、异常处理、避免注入Bean为null等。 下面根据引用内容详细展开: </think> ### Spring Boot中拦截器的配置与使用方法 #### 1. **创建自定义拦截器** 实现`HandlerInterceptor`接口并重写三个核心方法: ```java import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class AuthInterceptor implements HandlerInterceptor { // 请求到达Controller前执行(认证/日志等) @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String token = request.getHeader("Authorization"); if (!validateToken(token)) { response.sendError(401, "Invalid token"); return false; // 中断请求 } return true; // 放行请求 } // Controller执行后,视图渲染前执行(添加模型数据等) @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { modelAndView.addObject("requestTime", System.currentTimeMillis()); } // 请求完成后执行(资源清理/异常处理等) @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { if (ex != null) { log.error("Request failed: " + request.getRequestURI(), ex); } } private boolean validateToken(String token) { // 实现Token验证逻辑 return token != null && token.startsWith("Bearer "); } } ``` #### 2. **注册拦截器到Spring容器** 通过配置类实现`WebMvcConfigurer`并注册拦截器: ```java 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 WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new AuthInterceptor()) .addPathPatterns("/api/**") // 拦截所有/api路径 .excludePathPatterns("/api/public/**"); // 排除公开接口 // 可注册多个拦截器(按添加顺序执行) registry.addInterceptor(new LogInterceptor()); } } ``` #### 3. **高级配置技巧** 1. **多拦截器顺序控制** 通过`order()`方法指定优先级(数值越小优先级越高): ```java registry.addInterceptor(new AuthInterceptor()).order(1); registry.addInterceptor(new LogInterceptor()).order(2); ``` 2. **获取请求体内容** 使用`ContentCachingRequestWrapper`包装请求: ```java @Override public boolean preHandle(HttpServletRequest request, ...) { if (request instanceof ContentCachingRequestWrapper) { String body = new String( ((ContentCachingRequestWrapper)request).getContentAsByteArray(), StandardCharsets.UTF_8 ); } return true; } ``` 3. **依赖注入支持** 拦截器注入Spring Bean(需通过`@Component`声明): ```java @Component public class RateLimitInterceptor implements HandlerInterceptor { @Autowired private RedisTemplate<String, Object> redisTemplate; // ... } ``` #### 4. **最佳实践建议** - **职责单一**:每个拦截器只处理单一功能(如认证/日志/限流)[^4] - **执行顺序**:认证拦截器应放在首位(`order(1)`) - **性能优化**:避免在拦截器中进行数据库查询等耗时操作 - **异常处理**:在`afterCompletion`中统一处理异常[^2] - **静态资源排除**:通过`excludePathPatterns`排除静态资源路径 ```java .excludePathPatterns("/css/**", "/js/**", "/images/**") ``` > **重要提示**:在Spring Boot 3.x中可使用函数式注册方式: > ```java > @Bean > public WebMvcConfigurer interceptorConfig() { > return new WebMvcConfigurer() { > @Override > public void addInterceptors(InterceptorRegistry registry) { > registry.addInterceptor(new CustomInterceptor()); > } > }; > } > ``` #### 5. **典型应用场景** | 场景 | 实现方式 | 示例方法 | |-------------------|-----------------------------------|-------------| | 接口认证 | 在`preHandle`验证Token/权限 | [^5] | | 请求日志记录 | 在`preHandle`记录入参 | [^4] | | 接口限流 | 在`preHandle`检查Redis计数器 | [^2] | | 响应时间统计 | 在`preHandle`记录开始时间,在`afterCompletion`计算耗时 | [^4] | | 全局异常处理 | 在`afterCompletion`捕获异常 | [^2] | [^1]: Spring Boot中的拦截器配置。大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们来聊聊Spring Boot中的拦截器配置。拦截器是处理HTTP请求的一种机制,类似于Servlet过滤器,但它更强大且使用更加灵活。在Spring Boot中,拦截器用于在请求到达控制器之前请求完成之后进行一些预处理后处理操作。接下来,我们将深入探讨如何在Spring Boot中配置使用拦截器。 [^2]: Spring Boot拦截器(Interceptor)深度应用指南。 文章目录 一、拦截器基础概念1.1 什么是拦截器?1.2 拦截器 vs 过滤器 二、拦截器核心实现2.1 创建自定义拦截器2.2 注册拦截器 三、拦截器高级应用3.1 多拦截器执行顺序3.2 拦截器与异常处理方案1:在afterCompletion中处理方案2:结合@ControllerAdvice 3.3 拦截器与异步请求 四、实战应用场景4.1 认证与授权拦截4.2 请求日志记录4.3 接口限流控制 五、性能优化与最佳实践5.1 拦截器优化技巧5.2 常见问题解决方案问题1:拦截器不生效问题2:拦截器注入Bean为null问题3:拦截静态资源 六、Spring Boot 3.x新特性6.1 拦截器注册新方式6.2 函数式编程支持 七、总结与最佳实践7.1 拦截器适用场景总结7.2 项目实战建议。 [^4]: Spring Boot中拦截器的使用指南:从入门到精通。然后在拦截器中: @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (request instanceof ContentCachingRequestWrapper) { ContentCachingRequestWrapper wrappedRequest = (ContentCachingRequestWrapper) request; byte[] body = wrappedRequest.getContentAsByteArray(); String requestBody = new String(body, StandardCharsets.UTF_8); // 使用requestBody } return true; } 六、最佳实践建议 职责单一:每个拦截器只关注一个功能点性能考虑:避免在拦截器中做耗时操作合理排序:认证拦截器应该放在最前面异常处理:注意拦截器中的异常处理逻辑避免循环:拦截器逻辑不应导致循环重定向 七、总结。 [^5]: Spring Boot 配置拦截器 使用拦截器验证Token。import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值