spring项目启动时filter类加载不到bean的问题处理解决方法

一、我们先来分析一下错误信息的具体情况

首先,出现该问题时出现的报错信息如下:

主报错信息:

Exception starting filter [rfidUtils]

 报错信息解释为:异常启动过滤器 [rfidUtils]

 说明:rfidUtils是我项目中的一个filter工具类,对于大家来说,类名会和我的不同。

错误定位信息:

java.lang.NullPointerException: null

    at com.gainet.common.filter.RfidUtils.openTcpAll(RfidUtils.java:131)
    at com.gainet.common.filter.RfidUtils.init(RfidUtils.java:121)

 过滤器启动异常的原因:java.lang.NullPointerException: null

空指针异常出现的位置在:    

        at com.gainet.common.filter.RfidUtils.openTcpAll(RfidUtils.java:131)
        at com.gainet.common.filter.RfidUtils.init(RfidUtils.java:121)

 解释:在RfidUtils类的121行,调用了方法openTcpAll(),在openTcpAll()方法的131行,出现了空指针的异常。在这个位置调用了一个bean对象redisCache的方法

String redisEPC = redisCache.getCacheObject(epc);

bean对象redisCache的注入方式如下:

@Autowired
private  RedisCache redisCache;

二、我们再来分析一下问题出现的原因

问题出现是因为项目加载机制造成的

在spring项目启动时, 加载和初始化bean的顺序大致如下:

1、读取并解析项目的配置文件(如application.properties,application.yml)。

2、检测@Component和@Configuration等注解标注的类,并将其注册为bean。

3、扫描@ComponentScan指定的包路径,注册bean。

4、处理@PropertySource注解,加载更多的配置文件。

5、处理@Import注解,导入额外的配置类或者bean。

6、创建bean定义,这个阶段会应用@Bean定义,后处理器等。

7、应用bean的后处理器(如AutowiredAnnotationBeanPostProcessor)来注入依赖。

8、初始化bean(如果实现了InitializingBean接口,调用afterPropertiesSet方法,如果有@PostConstruct注解,调用这个注解标注的方法)。

9、最后,bean可以使用了,如果配置了lazy-init,则在容器启动时bean不会被初始化。

注意:具体的加载顺序可能会受到其他配置(如@Conditional注解等)的影响。

 filter类在 2、检测@Component和@Configuration等注解标注的类 时加载,此时RedisCache类还没有被加载,所以就报错了。

在filter类中使用@Autowired等方式注入bean是不行的。

三、我们确定下解决方案

1、给filter类RfidUtils加上@Component注解,将该类交给spring管理。

@Component
public class RfidUtils implements Filter {}

2、让filter类RfidUtils 实现 ApplicationContextAware 接口,将applicationContext容器存起来备用。

@Component
public class RfidUtils implements Filter, ApplicationContextAware { 
        private static ApplicationContext applicationContext;    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext)         throws BeansException {
            this.applicationContext = applicationContext;
        }
}

3、 在filter类的init方法中,用applicationContext容器通过getBean方法加载bean对象并存入变量备用。

@Component

public class RfidUtils implements Filter, ApplicationContextAware { 
        private static ApplicationContext applicationContext;    

        private static RedisCache redisCache;

        @Override         

        public void setApplicationContext(ApplicationContext applicationContext)  throws         BeansException {         

                this.applicationContext = applicationContext;        

         }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException{
        this.redisCache=applicationContext.getBean(RedisCache.class);
        openTcpAll();
    }
}

 4、此时,我们在filter类中通过变量redisCache就可以调用RedisCache类了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

itmengzhaojie

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值