关于Spring Filter中无法使用注入Bean的问题以及解决方案

这里涉及到一个小知识点就是web项目在启动时的加载顺序:


 

<context-param> 用来加载你配置的文件信息

<listener> 配置你的监听服务

<filter> 过滤器配置你单独的一些操作

<servlet> 容器初始化

        加载顺序为:context-param -> listener -> filter -> servlet    加载的顺序不受在web.xml中配置的位置影响


 Filter 中的三个方法

init方法:    (生)容器中过滤器生成的时候调用;

destroy方法:  (死)容器中过滤器销毁的时候调用

doFilter方法:  过滤器的主要代码

为什么会出现Autowired注入后 bean为null的情况?

这是因为当在filter中配置了bean后,加载时你的bean还没有被初始化,filter在初始化的时候,注解的bean还没有被初始化,所以会出现注入对象为null的情况。

那么如何解决这个问题呢?

  • 通过Spring为我们提供的 ApplicationContextAware 来进行初始化。(不懂的小伙伴自行百度一下)
  • ApplicationContextAware 通过它Spring容器会自动把上下文环境对象调用ApplicationContextAware接口中的setApplicationContext方法。
  • 我们在ApplicationContextAware的实现类中,就可以通过这个上下文环境对象得到Spring容器中的Bean。

提供一个工具类:


import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.web.servlet.LocaleResolver;

@Component
public final class SpringUtils implements ApplicationContextAware, DisposableBean {
    private static ApplicationContext applicationContext;

    public SpringUtils() {
    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        applicationContext = applicationContext;
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public void destroy() throws Exception {
        applicationContext = null;
    }

    public static <T> T getBean(String name) throws BeansException {
        return applicationContext.getBean(name);
    }

    public static String getProperty(String name) {
        return applicationContext.getEnvironment().getProperty(name);
    }

    public static <T> T getBean(Class<T> clz) throws BeansException {
        Assert.notNull(clz);
        T result = applicationContext.getBean(clz);
        return result;
    }

    public static <T> T getBean(String name, Class<T> type) {
        Assert.hasText(name);
        Assert.notNull(type);
        return applicationContext.getBean(name, type);
    }

    public static boolean containsBean(String name) {
        Assert.hasText(name);
        return applicationContext.containsBean(name);
    }

    public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
        Assert.hasText(name);
        return applicationContext.isSingleton(name);
    }

    public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
        Assert.hasText(name);
        return applicationContext.getType(name);
    }

    public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
        Assert.hasText(name);
        return applicationContext.getAliases(name);
    }

    public static String getMessage(String code, Object... args) {
        LocaleResolver localeResolver = (LocaleResolver)getBean("localeResolver", LocaleResolver.class);
        Locale locale = localeResolver.resolveLocale((HttpServletRequest)null);
        return applicationContext.getMessage(code, args, locale);
    }
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值