SpringBoot使用ApplicationContext.getBean启动报空指针处理记录

问题:项目启动报空指针

定位:新增filter中init方法使用getbean控制

解决:在新增filter上加注解

@DependsOn({"applicationContextUtils"})
@Component
@DependsOn({"applicationContextUtils"})//此处解决空指针问题
public class XssFilter implements Filter{
    @Autowired
    private MultipartResolver multipartResolver=null;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //注入bean
        multipartResolver=(MultipartResolver) ApplicationContextUtils.getApplicationContext().getBean("multipartResolver",MultipartResolver.class);
    }
}
package com.bonc.ds.web.utils;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;

import java.util.Locale;

//对Spring容器进行各种上下文操作的工具类
@Configuration
public class ApplicationContextUtils implements ApplicationContextAware {

    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        ApplicationContextUtils.context = context;
    }

    public static ApplicationContext getApplicationContext(){
        return context;
    }
    //根据Bean名称获取Bean对象
    public static Object getBean(String beanName){
        return context.getBean(beanName);
    }

    public static Object getMassage(String key){
        return context.getMessage(key, null, Locale.getDefault());
    }
}

分析:

ApplicationContextUtils是否在Configuration的Bean初始化之前初始化是未知的。

用到的@DependsOn注解,先把SpringContextUtils注册到Spring容器里面

注解含义就是组件A要依赖于另一个组件B,也就是说被依赖的组件B会比组件A先注册到Spring容器中

<think>嗯,用户遇到了使用applicationContext.getBean时出现的错问题,需要分析原因并提供解决方案。首先,我得回忆一下Spring框架中Bean的获取机制。常见的错误可能有Bean未定义、名称不匹配、作用域问题、上下文未正确初始化等。 用户提到的NoSuchBeanDefinitionException,说明Spring容器中找不到对应的Bean。可能的原因之一是Bean没有被正确注册。比如,可能忘记在配置类或XML中声明Bean,或者组件扫描的路径不对,导致Spring没有扫描到相关的类。这时候需要检查@ComponentScan注解或者XML配置中的包路径是否正确。 另一个情况是Bean名称不匹配。用户可能在getBean时用了默认的类名,而实际Bean的名称可能因为注解的不同而改变。例如,使用@Service("myService")指定了名称,但getBean时还是用类名,就会出错。这时候需要确认Bean的名称是否一致,或者在getBean使用类类型而不是名称。 作用域问题也可能导致错误。比如,如果Bean的作用域是prototype,可能在某些情况下没有被正确实例化。不过更常见的是Web作用域如request或session在非Web环境中使用,导致Bean无法创建。这时候需要检查作用域配置是否合适。 ApplicationContext未正确初始化也是一个可能的原因。特别是在非Spring管理的类中手动获取ApplicationContext时,可能需要通过实现ApplicationContextAware接口来注入上下文。如果工具类没有正确初始化,会导致空指针异常,这时候需要确保SpringContextUtils类正确实现了ApplicationContextAware,并且被Spring管理。 另外,Bean的延迟加载(@Lazy)可能导致在需要时还未创建,从而引发异常。还有,项目配置错误如缺少依赖或配置冲突,也可能导致容器启动失败,进而无法获取Bean。查看启动日志中的Error starting ApplicationContext提示,根据调试信息调整配置。 解决方案方面,首先要检查Bean是否正确定义,确保组件扫描覆盖到相关包。其次,使用正确的Bean名称或类类型来获取Bean。然后,确认作用域配置正确,避免在非Web环境使用Web作用域。接着,确保ApplicationContext被正确初始化,特别是在工具类中。最后,检查项目依赖和配置,处理可能的冲突或缺失。 用户提供的引用内容中,引用[1]提到使用getBean导致NoSuchBeanDefinitionException,引用[2]和[3]讨论了通过ApplicationContextAware获取上下文的方法,引用[4]指出启动错误需要调试,引用[5]列举了Bean名称冲突的情况。综合这些信息,需要逐一排查可能的原因,并根据具体情况调整配置或代码。</think>### Spring中`applicationContext.getBean()`错原因及解决方案 #### 一、常见错原因 1. **Bean未定义或未扫描到** - **原因**:Bean未通过`@Component`、`@Service`等注解声明,或组件扫描路径未覆盖该Bean所在的包。 - **示例错误**:`NoSuchBeanDefinitionException: No bean named 'userService' available`[^1][^5]。 2. **Bean名称或类型不匹配** - **原因**:使用`getBean("beanName")`时名称拼写错误,或通过类类型获取时存在多个同类型Bean[^5]。 - **示例错误**:`No qualifying bean of type 'X' available: expected single matching bean but found 2`。 3. **Bean作用域问题** - **原因**:尝试获取的Bean作用域为`prototype`或Web作用域(如`request`),但未正确初始化。 4. **ApplicationContext未正确注入** - **原因**:未通过`ApplicationContextAware`注入上下文,导致`applicationContext`为空[^2][^3]。 - **示例错误**:`NullPointerException`或`NoSuchBeanDefinitionException`[^3][^4]。 5. **配置或依赖错误** - **原因**:项目启动失败(如`Error starting ApplicationContext`),导致Bean未加载。 --- #### 二、解决方案 ##### 1. 检查Bean定义与扫描路径 - **步骤**: - 确保Bean类添加了`@Component`、`@Service`等注解。 - 检查`@ComponentScan`或XML配置中的包路径是否包含Bean所在包。 ```java @SpringBootApplication @ComponentScan("com.example") // 确保路径正确 public class Application { ... } ``` ##### 2. 修正Bean名称或类型 - **场景1:明确指定Bean名称** ```java @Service("myService") // 自定义名称 public class MyService { ... } // 通过名称获取 MyService service = applicationContext.getBean("myService"); ``` - **场景2:通过类类型获取(避免名称冲突)** ```java // 确保唯一Bean MyService service = applicationContext.getBean(MyService.class); ``` ##### 3. 处理作用域问题 - **示例**:在非Web环境中避免使用`@Scope("request")`,改用默认的`singleton`或`prototype`。 ```java @Service @Scope("prototype") public class TaskProcessor { ... } ``` ##### 4. 正确初始化ApplicationContext - **实现`ApplicationContextAware`**: ```java @Component public class SpringContextUtils implements ApplicationContextAware { private static ApplicationContext context; @Override public void setApplicationContext(ApplicationContext ctx) throws BeansException { context = ctx; } public static <T> T getBean(Class<T> clazz) { return context.getBean(clazz); } } ``` **调用方式**: ```java MyService service = SpringContextUtils.getBean(MyService.class); ``` ##### 5. 修复项目配置 - **检查启动日志**: - 若出现`Error starting ApplicationContext`,添加`debug`模式重新运行,根据日志修复依赖或配置冲突。 ```bash java -jar myapp.jar --debug ``` --- #### 三、典型问题示例 **问题**:工具类中`applicationContext`为空 **解决方案**: 1. 确保工具类被Spring管理(如添加`@Component`)。 2. 实现`ApplicationContextAware`接口并注入上下文[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值