首页 > 其他分享 >解决非Spring Bean访问Spring Bean的问题:实用指南

解决非Spring Bean访问Spring Bean的问题:实用指南

时间:2024-07-31 09:31:01浏览次数:9  
标签:指南 Spring SpringBean Bean org import public PlainClass

在非SpringBean类里获取SpringBean,会是什么情况?

case1

下面这段代码中,PlainClass 表示一个普通Java类:

public class PlainClass {

    public void foo1() {
        TheOtherBean bean = SpringContextUtils.getBean(TheOtherBean.class);
        System.out.println(bean);
    }
}


import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringContextUtils implements ApplicationContextAware {
    /**
     * Spring容器上下文对象实例
     */
    private ApplicationContext applicationContext;

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

    public <T> T getBean(Class<T> clazz) {
        return applicationContext.getBean(clazz);
    }
 
}

我们在SpringBean里执行 PlainClass#foo1 是没问题的。

而在非SpringBean中执行 PlainClass#foo1,会抛空指针异常,这是因为在这种情况下,SpringContextUtils未被Spring容器管理,无法获取到applicationContext对象。

java.lang.NullPointerException
    at jstudy.redislimit.SpringContextUtils.getBean(SpringContextUtils.java:30)
    at jstudy.beantest.PlainClass.foo1(PlainClass.java:12)
    at jstudy.beantest.BeanTest.test(BeanTest.java:18)

 

 

case2

接着看下面代码中的 PlainClass :

import org.springframework.beans.factory.annotation.Autowired;

public class PlainClass {
    @Autowired
    private TheOtherBean theOtherBean;

    public void foo2() {
        System.out.println(theOtherBean);
    }
}


import org.springframework.stereotype.Component;

@Component
public class TheOtherBean {
}

此时,在SpringBean 里执行 PlainClass#foo2 , 输出结果是什么?

 

 

是null。也就是说 theOtherBean 对象是null。为什么? 因为Spring启动时,程序先加载的是 PlainClass 类(它不受Spring管理),而此时`TheOtherBean`尚未被注入容器里,自动装配失败,注入的`TheOtherBean`为null。

当然, 我们通常在项目中不会写这种烂代码来“博人眼球”。

 

细心的同学可以发现,IDE会在 PlainClass 这个非SpringBean里使用的@Autowired注解上给出警告,提示"Autowired members must be defined in valid Spring bean (@Component|@Service|...)",提醒开发者合适地定义Bean以避免这类问题。

 image.png

 

另外,在非SpringBean 里执行 PlainClass#foo2呢?依然是null。

 

 

附上我所使用的测试类代码

package jstudy.beantest;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest
@RunWith(SpringRunner.class)
public class BeanTest {
    @Test
    public void test() {
        new PlainClass().foo2();
    }
}

该测试类`BeanTest`在SpringBoot环境下运行。注释掉 @SpringBootTest 和 @RunWith(SpringRunner.class)后,`BeanTest`就是一个非SpringBean(普通Java类)了。

 

 

总结

在非SpringBean类中直接获取SpringBean可能会引发问题,例如上面案例里提到的空指针和自动装配失败。为避免这些问题,建议将需要访问Spring Bean的类也注册为Spring Bean,以确保依赖关系得到正确管理。

标签:指南,Spring,SpringBean,Bean,org,import,public,PlainClass
From: https://www.cnblogs.com/buguge/p/18333846

相关文章

  • SpringIoC-依赖注入源码解析
    目录1.依赖注入底层原理流程图2.Spring中到底有几种依赖注入的方式?2.1手动注入 2.2自动注入2.2.1XML的autowire自动注入2.2.2@Autowired注解的自动注入3.寻找注入点3.1static的字段或方法为什么不支持3.2桥接方法4.注入点进行注入4.1字段注入4.2Set......
  • Spring源码(八)--Spring实例化的策略
    Spring实例化的策略有几种,可以看一下InstantiationStrategy相关的类。UML结构图InstantiationStrategy的实现类有SimpleInstantiationStrategy。CglibSubclassingInstantiationStrategy又继承了SimpleInstantiationStrategy。InstantiationStrategyInstantiationStrat......
  • springboot项目使用自定义starter
    首先是自定义的starter部分pom文件<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation=&......
  • spring boot(学习笔记第十五课)
    springboot(学习笔记第十五课)Springboot的websocket(广播)学习内容:Springboot的websocket(广播)1.Springboot的websocket(广播)回顾下webserver的进化第一代Web程序,使用整体页面刷新技术,对整个页面进行刷新。缺点:明明不需要的页面部分,也要全部刷新,对于网络带......
  • Springboot3集成knife4j,swagger实现在线接口文档
    什么是knife4jknife4j是一个集Swagger2和OpenAPI3为一体的增强解决方案,帮助开发者快速聚合使用OpenAPI规范,快速生成API文档,并且提供一些额外的功能,比如:API文档生成:可以根据Controller和方法上的注解自动生成Markdown格式的API文档在线访问API:可以在knife4j的页面直接访问......
  • 基于springboot学生毕业离校系统lw(毕设+实现+源码+数据库)
    摘 要一年一度的毕业季的到来,方方面面都普及使得学生毕业离校系统的开发成为必需。学生毕业离校系统主要是借助计算机,通过对学生、教师、离校信息、费用结算、LW审核等信息进行管理。为减少管理员的工作,同时也方便广大学生对个人所需毕业离校的及时查询以及管理。学生毕......
  • 基于springboot音乐网站与分享平台(毕设+实现+源码+数据库)
                           摘要本LW主要论述了如何使用JAVA语言开发一个音乐网站与分享平台,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构,面向对象编程思想进行项目开发。在引言中,作者将论述音乐网站与分享平台......
  • 记录些Spring+题集(32)
    10Wqps评论中台架构评论系统的业务分析在B站,UP主每天都会发布海量的视频、动态、专栏等内容,随之而来的是弹幕和评论区的各种讨论。播放器中直接滚动播放的弹幕,如同调味剂,重在提升视频观看体验;而点进评论区,相对而言评论文本更长,内容的观点、形式都更丰富,更像是饭后甜点。随着......
  • 用idea实现第一个springBoot
    hello@Controller@RequestMapping("/hello")publicclassHelloController{@GetMapping("/hello")@ResponseBodypublicStringhello(){return"hello";}} 更改端口号#更改端口号server.port=8081banner.tx......
  • 工时管理系统对比指南:找到适合你的
    国内外主流的10款工时管理平台对比:PingCode、Worktile、Todoist、ClickUp、滴答清单、专注清单、一木清单、NarTick、Tweek、朝暮计划。在选择合适的工时管理平台时,你是否感到挑战重重?市场上的各种选项似乎都声称能够提升效率和减轻管理负担,但是真正适合你团队的系统究竟应该具......