springboot获取getBean方法以及ApplicationContext空指针问题解决

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot获取getBean方法以及ApplicationContext空指针问题解决相关的知识,希望对你有一定的参考价值。

参考技术A 场景:在springboot多模块中使用getBean获取bean导致空指针异常。

假如有个工程有 common模块 和 admin(启动类模块)模块 ,获取getBean的类在admin中,则不会报空指针,如果在common模块中,在admin模块中调用,则会报空指针异常,解决方法,使用 @Import 导入getBean方法所在的类

SpringBoot 获取上下文,获取bean的几种中方式


传统Spring项目

在写传统的spring项目中,一般通过初始化抽象类AbstractXmlApplicationContext 的实现类,并传入spring.xml,来获取应用上下文,最终通过getBean方法获取bean,如下:

ApplicationContext app1 = new FileSystemXmlApplicationContext("applicationContext.xml");
app1.getBean("beanName");
ApplicationContext app2 = new ClassPathXmlApplicationContext("applicationContext.xml");
app2.getBean("beanName");

SpringBoot项目获取bean的几种方式

1. 通过启动类中返回的上下文获取

ConfigurableApplicationContext app = SpringApplication.run(BeanDemoApplication.class, args);
SpringUtil.setAppContext(app);
public class SpringUtil 

private static ApplicationContext appContext;

public static void setAppContext(ApplicationContext appContext)
SpringUtil.appContext = appContext;


public static ApplicationContext getAppContext()
return appContext;


在第三方类中使用:

ApplicationContext appContext = SpringUtil.getAppContext();
appContext.getBean("beanName");

2. 通过工具类获取

​RequestContextUtils.findWebApplicationContext(HttpServletRequest request)​​,​​WebApplicationContextUtils.getWebApplicationContext(ServletContext sc)​

a. 在controller中传入request,例如:

public String test(HttpServletRequest request,HttpServletRequest response) 
WebApplicationContext wc = RequestContextUtils.findWebApplicationContext(request);
wc.getBean("beanName");

WebApplicationContext wc2 = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext());
wc2.getBean("beanName");

b. 在service中或者其他后端服务中获取:

HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
WebApplicationContext wc = RequestContextUtils.findWebApplicationContext(request);
WebApplicationContext wc2 = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext());

wc.getBean("beanName");
wc2.getBean("beanName");

3. 通过实现接口ApplicationContextAware

@Component
public class TestApplicationContextAware implements ApplicationContextAware

private ApplicationContext applicationContext;

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
this.applicationContext = applicationContext;


public Object getBean(String beanName)
return applicationContext.getBean(beanName);


public ApplicationContext getApplicationContext()
return applicationContext;


在其他类中调用

@Autowired
private TestApplicationContextAware app;
public void testMethod()
app.getBean("beanName");

4. 通过继承抽象类:ApplicationObjectSupport,WebApplicationObjectSupport

原理参考第3点

5. 其他方式

在网上看,发现也可以直接调用:ContextLoader.getCurrentWebApplicationContext(),或者 ContextLoaderListener.getCurrentWebApplicationContext() 其实都是调用同一段代码,如下:

@Nullable
public static WebApplicationContext getCurrentWebApplicationContext()
ClassLoader ccl = Thread.currentThread().getContextClassLoader();
if (ccl != null)
WebApplicationContext ccpt = currentContextPerThread.get(ccl);
if (ccpt != null)
return ccpt;


return currentContext;

说明:目前通过这种方式获取上下文为null,从代码可以看出,上下文是通过​​currentContextPerThread.get(ccl)​​​ 来获取的,而currentContextPerThread缓存是通过方法​​contextInitialized(ServletContextEvent event)​​ 来初始化的,至于为何获取为空





以上是关于springboot获取getBean方法以及ApplicationContext空指针问题解决的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot多模块项目ApplicationContext无法getBean,MybatisPlus二级缓存与放弃Mybatis(Plus)的二级缓存

玄学springboot applicationcontext.getBean(用类名String还是类型Class), getBean(..)的调用场景结果不同?getBean(..)还会阻塞?@D

Spring - 解决 SpringUtil getBean NPE 问题

Spring - 解决 SpringUtil getBean NPE 问题

SpringBoot 获取上下文,获取bean的几种中方式

踩坑了!使用 @Autowired 注入成功,GetBean 方法却获取不到?!