Spring 静态变量/构造函数注入失败的解决方案

目录
  • 1、案例1:Spring对静态变量的注入为空
  • 2、案例2:在构造函数中使用Spring容器中的Bean对象,得到的结果为空
  • 补充

1、案例1:Spring对静态变量的注入为空

案例代码如下:

@Component
public class HelloWorld {
   /**
    * 错误案例:这种方式是不能给静态变量注入属性值的
    */
    @Value("${hello.world}")
    public static String HELLO_WORLD;
}

解决方案一:@Value注解加在setter方法上面

@Component
public class HelloWorld {
    public static String HELLO_WORLD;

    @Value("${hello.world}")
    public void setHELLO_WORLD(String HELLO_WORLD) {
        this.HELLO_WORLD = HELLO_WORLD;
    }
}

解决方案二:@PostConstruct注解

因为@PostConstruct注解修饰的方法加在顺序在构造方法之后静态变量赋值之前,所以可以通过该注解解决静态变量属性值注入失败问题:

@Component
public class HelloWorld {
    public static String HELLO_WORLD;

    @Value("${hello.world}")
    public static String helloWorld;

    @PostConstruct
    public void init(){
        // 为静态变量赋值(值为从Spring IOC容器中获取的hello.world字段值)
        HELLO_WORLD = this.helloWorld;
    }
}

2、案例2:在构造函数中使用Spring容器中的Bean对象,得到的结果为空

业务场景假设:

eg:我需要在一个类(HelloWorld)被加载的时候,调用service层的接口(UserService)去执行一个方法(sayHello),有些同学可能会在构造函数中通过调用UserService的sayHello()去实现这个需求,但是这会导致一些错误异常,请看下面的示例。

错误演示代码如下:

@Component
public class HelloWorld {

   /**
    * UserService注入
    */
    @Autowired
    private UserService userService;

    public HelloWorld(){
       // 这里会报空指针异常:因为 userService 的属性注入是在无参数构造函数之后,如果这里直接使用 userService ,此时该属性值为null,一个为null的成员变量调用sayHello()方法,NullPointException 异常是情理之中呀!
       userService.sayHello("hello tiandai!");
    }
}

解决方案:@PostConstruct注解

由于@PostConstruct注解修饰的方法其生命周期位于构造方法调用之后,在Spring属性值注入之前,所以,该注解可以很好的解决这个业务需求,代码如下:

@Component
public class HelloWorld {

   /**
    * UserService注入
    */
    @Autowired
    private UserService userService;

    public HelloWorld(){
    }

    @PostConstruct
    public void init(){
       userService.sayHello("hello tiandai!");
    }
}

补充

关于这一部分问题,还有一些奇奇怪怪的用法

在构造函数里使用@Value注入的属性值获取不到

在配置mqtt连接的时候是在bean初始化的时候就进行连接, 所以要配置连接参数, 当时用的是这样的方式.

结果运行的时候一直会报NullPointer异常,网上找了很多方案都没效果,  后来发现 controller里是可以注入成功的,  那么说明依赖注入是在构造函数之后进行的.     用以下方式可解决.

还有一点 , @Value 属性是不可以static修饰的,否则也取不到值。

到此这篇关于Spring 静态变量/构造函数注入失败的解决方案的文章就介绍到这了,更多相关Spring 静态变量 构造函数注入失败内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2021-11-24

spring 如何将配置信息注入静态变量的方法

我们学习过将配置信息,通过@Value()的方法注入到对象的变量.这是由于对象是由spring来托管的.那么非spring如果,我们需要在静态方法中,使用配置文件中的值,又该怎么做呢? 传统的错误作法 application.properties spring.redis.host=test @Component public class RedisServiceImpl implements RedisService { ... @Value("${spring.redis.host}&quo

spring通过构造函数注入实现方法分析

本文实例讲述了spring通过构造函数注入实现方法.分享给大家供大家参考,具体如下: 一 通过构造函数注入 set注入的缺点是无法清晰表达哪些属性是必须的,哪些是可选的,构造注入的优势是通过构造强制依赖关系,不可能实例化不完全的或无法使用的bean. 二 举例 1 Employee package com.hsp.constructor; public class Employee { private String name; private int age; public Employee(S

使用Springboot注入带参数的构造函数实例

我们使用@Service注解一个service,默认注入的是不带参的构造函数,如果我们需要注入带参的构造函数,怎么办? 使用@Configuration+ @Bean注解来实现注入: @Configuration public class BlockChainServiceConfig { @Bean BlockChainService blockChainService(){ return new BlockChainService(1); } } service类 public class

Spring对静态变量无法注入的解决方案

Spring对静态变量无法注入 问题 今天在学习的过程中想写一个连接和线程绑定的JDBCUtils工具类,但测试时发现一直报空指针异常,上网查了之后Spring并不支持对静态成员变量注入,所以光试用@Autowired肯定是不行的. 可是我们编写工具类时肯定是要使用静态变量和方法的,我总结一下我用过可以实现对静态成员变量注入的方法. @Component public class JDBCUtils { @Autowired private static ComboPooledDataSourc

SpringBoot使用@Value实现给静态变量注入值

SpringBoot中使用@Value()只能给普通变量注入值,不能直接给静态变量赋值 例如 application-dev.properties 配置文件有如下配置: 给普通变量赋值时,直接在变量声明之上添加@Value()注解即可,如下所示: 当要给静态变量注入值的时候,若是在静态变量声明之上直接添加@Value()注解是无效的,例如: 虽然没有编译和运行上的报错,经调试可知这种注解方式mailUsername.mailPassword.mailHost的值都是null,也就是说直接给静态变

spring boot静态变量注入配置文件详解

本文实例为大家分享了spring boot静态变量注入配置文件的具体代码,供大家参考,具体内容如下 spring 静态变量注入 spring 中不支持直接进行静态变量值的注入,我们看一下代码: @Component(value = "KafkaConfig") @ConfigurationProperties(prefix = "baseConfig") public class KafkaConfig { private static String logBrok

springboot 使用yml配置文件给静态变量赋值教程

声明: 此处需求是修改封装的clickhouseUtil数据查询引擎连接工具类.由于此类中的方法都是静态方法.连接地址等参数需要根据不同环境改变.例如开发下地址,测试下地址,生产地址等,所有通过配置文件来获取不同环境下的配置参数,但是使用的方法是静态的,所有不能使用一般情况下的@value直接给变量赋值,需要用到spring 属性的set方法来给静态变量赋值,然后静态方法使用静态变量即可 方法: 第一步:在yml文件中配置需要的参数 clickhouse: address: jdbc:click

Spring boot工具类静态属性注入及多环境配置详解

由于需要访问MongoDB,但是本地开发环境不能直接连接MongoDB,需要通过SecureCRT使用127.0.0.2本地IP代理.但是程序部署到线上生产环境后,是可以直接访问MongoDB的,因此开发好程序后,总是要修改一下MongoDB服务器的IP才能提交代码,这样很是不方便. private static final String PUBCHAT_HOST = "127.0.0.2"; // private static final String PUBCHAT_HOST =

Spring Boot使用Value注解给静态变量赋值的方法

昨天在使用@Value注解给静态变量赋值的时候,发现静态变量的值始终是null.后来搜索一下得知其中原因,Spring Boot 不允许/不支持把值注入到静态变量中.但是我们可以变通一下解决这个问题.因为Spring Boot 支持set方法注入,我们可以利用非静态set方法注入静态变量.废话不多说,贴上我昨天写的代码: @Component public class CoverImageUtil { private static String endpoint; private static

浅谈Android中关于静态变量(static)的使用问题

项目中,在不停地接收串口数据很长一段时间(几小时)后,会偶然性的报错.初步排除了oom和cpu紧张问题,因为是工业平板不方便调试,用了些比较笨的方法最后锁定在几个用了static的地方.在这里记录下Android中使用static的一些问题. 静态变量的生命周期遵守Java的设计.静态变量在类被load的时候分配内存,并存在于方法区.当类被卸载时,静态变量被销毁.在PC机的客户端程序中,一个类被加载和卸载,可简单的等同于jvm进程的启动和结束.在Android中,用的DVM也是一样的,不过And

Android静态变量的生命周期 简单介绍

Android是用Java开发,其静态变量的生命周期遵守Java的设计.我们知道静态变量是在类被load的时候分配内存的,并且存在于方法区.当类被卸载的时候,静态变量被销毁.在PC机的客户端程序中,一个类被加载和卸载,可简单的等同于jvm进程的启动和结束.那么在Android中呢?用的Dalvik vm也是一样的.不过Android不太突出的进程概念,所以对静态变量的生命周期就会感觉模糊,这种模糊对于值类型是无所谓的,如果是静态的对象引用,则与内存回收.内存泄漏这些问题有关,有必要加深研究和理解

Java成员变量默认值原理详解

如果我们不做任何初始化工作,变量具有什么默认值,或者是否具有默认值呢? 其实,成员变量在创建时,系统会为其分配一个默认值.不同类型的变量,默认值也不相同,下面来看看各种类型的默认值分别是什么. 用例子来说明:先输入一个java代码(这里只包括了实例变量) class Text1 { // 实例成员变量 private boolean bool; private byte b; private short s; private char c; private int i; private long

Spring不能注入Static变量的原因及Spring注入静态变量

下面给大家介绍spring不能注入static变量的原因,具体详情如下所示: Spring 依赖注入 是依赖 set方法 set方法是 是普通的对象方法 static变量是类的属性 @Autowired private static JdbcTemplate jdbcTemplate; 单纯看这个注入过程是没有报错的,但是在接下来的jdbcTemplate.query()会报空指针错误. ps:Spring注入静态变量 今天碰到一个问题,我的一个工具类提供了几种静态方法,静态方法需要另外一个类的

springboot无法从静态上下文中引用非静态变量的解决方法

静态方法可以不用创建对象就调用,非静态方法必须有了对象的实例才能调用. 因此想在静态方法中直接引用非静态方法是不可能的,因为不知道调用哪个对象的非静态方法,编译器不可能给出答案,因为没有对象. java就怕找不到对象. 解决办法: spring的set注入方法,通过非静态的setter方法注入静态变量,样例如下 @PropertySource(value = {"classpath:config/application.yml"},ignoreResourceNotFound = tr

Java如何读取配置文件并赋值静态变量

应用场景 项目开发中某个功能需要抽取成方法写成一个工具类,提供给别人使用.写过工具类的人都知道,工具类中的方法一般都是静态方法,可以直接使用类名点方法名调用, 使用很方便,比如判断某个对象是否为null的方式Objects.equals().由于我写的这个工具类中需要读取配置文件中的内容,可是常规方式注入成员变量时都不是静态的,不 能直接调用,比如这种方式: @Data @Component public class GBaseApiConfig { @Value("${gbase.api.pr