详解Spring如何注入静态变量

 更新时间:2023年06月26日 10:27:36   作者:东方甲乙木土  
这篇文章主要为大家详细介绍了Spring是如何注入静态变量的,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的小伙伴可以了解一下

为什么 Spring 不可以注入静态变量

@Autowired 不能注入 static 成员属性

静态变量和静态方法属于类,而 Spring 容器中管理的是对象,使用 @Autowired 注入的是容器中的对象实例,静态变量和方法是不能直接使用 @Autowried 注入的。

Spring 不建议开发代码中为静态变量注入属性值,类加载时会优先加载静态变量,此时 Spring 的上下文环境还没有完成加载,因此不可以为静态变量绑定值。

另一方面,在 @Autowired 注解注入扫描 Class 类原数据时,会直接忽略类的使用 static 关键字标识的成员。

使用 @Value 读取配置文件时,配置文件内容会作为 Properties 对象的属性管理在容器中,使用注解加载到变量上时就是使用容器注入的机制将配置内容赋值给相应属性。

@Value 注解标注静态变量

如果 @Value 注解标注在 static 或 final 变量,并不能将属性值注入,最终得到的变量值是 null。

Spring 注入内容到静态变量中

@Value + set 方法注入静态变量

如果想要为 static 变量注入值,可以间接的操作方式,比如可以通过注解标注在 set 方法(非静态)上,使用 set 方法注入的方式将属性值赋值到静态变量中。

 @Component
 public class Customer {
     private static String name;
     @Value("${customer.name}")
     public void setName(String name) {
         Customer.name = name;
     }
 }

定义静态方法工具类时,则不建议在工具类中使用注入的内容,因为工具类定义的是静态方法,使用时容器并没有加载完成,容易出现 NPE 问题。

Properties 注入静态变量

Properties 作为 java.util 包中用来读取配置文件的类,其本身是一个 Hashtable,可以将 *.properties 配置文件内容以键值对的形式存储在对象中。

Properties 使用时可以通过 load() 方法自定义指定需要读取的配置文件,通过流的方式读取文件中内容,并通过 getProperty() 方法读取指定配置信息。

因为 Properties 是通过读取文件内容来获取配置文件,不依赖 Spring 容器的加载,只要指定读取配置文件后,就可以获取到对应的属性,可以在加载类时赋值到静态变量。

具体使用方法为

Properties 读取文件工具类

public class PropertiesUtil {
    private static Properties readProperties(String configFile) {
        Properties properties = new Properties();
        try {
           properties.load( new ClassPathResource(path).getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return properties;
    }
}

使用 Properties 注入静态变量

@Component
 public class Customer {
     private static Properties properties = PropertiesUtil.readProperties("application.properties");
     private static String name = properties.getProperty("name");
 }

Properties 作为 Java 工具包中读取配置文件的类,可以读取配置并赋值给静态变量,但是 Properties 仅可以读取 .properties 配置文件,而不可以解析 .yml 配置文件。

详细的 Properties 使用方法可见:SpringBoot 使用 Properties 读取配置文件

Environment 注入静态变量

Spring 中有一个类 Environment,它可以被认为是当前应用程序正在运行的环境,继承了 PropertyResolver 接口,因此可以作为一个属性解析器使用。

Environment 可以从容器中注入,并使用对象的 getProperty() 方法来获取属性值。

只要在类加载静态属性时获取到初始化的 Environment 对象信息,就可以为静态变量赋值。

可以通过 @Autowired + set 方法将 Environment 对象注入到静态变量中,然后使用静态变量获取配置项即可。

@Component
public class Customer {
    private static Environment env;
    @Autowired
    public void setEnvironment(Environment environment) {
        env = environment;
    }
    private static String name =  env.getProperty("name");
}

Environment 可以读取 .properties 配置文件和 .yml 配置文件,是更好的一种选择。

综述

综上所述,有如下结论:

  • 在 Spring 项目中不建议将内容注入到静态变量中,因此稍有疏忽则会出现 NPE 问题
  • 如果使用 @Component、@Value、@Autowired 等注解委婉的实现了注入到静态变量中,但其终究还是在 Spring 容器加载之后进行加载赋值的,实际使用仍依赖 Spring 容器环境
  • 如果是单纯的 Java 静态工具类,则应该使用 Properties 类加载文件的方式,这样才可以完全不依赖 Spring 环境的运行。

到此这篇关于详解Spring如何注入静态变量的文章就介绍到这了,更多相关Spring注入静态变量内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java中实现list或set转map的方法

    java中实现list或set转map的方法

    这篇文章主要介绍了java中实现list或set转map的方法的相关资料,需要的朋友可以参考下
    2017-01-01
  • 深入浅出解析Java ThreadLocal原理

    深入浅出解析Java ThreadLocal原理

    ThreadLocal是JDK包提供的,它提供线程本地变量,如果创建一乐ThreadLocal变量,那么访问这个变量的每个线程都会有这个变量的一个副本,在实际多线程操作的时候,操作的是自己本地内存中的变量,从而规避了线程安全问题,感兴趣的朋友快来看看吧
    2021-11-11
  • 详解Struts2中配置默认Action的方法

    详解Struts2中配置默认Action的方法

    本篇文章主要介绍了详解Struts2中配置默认Action的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • 使用@RequiredArgsConstructor注解来取代繁琐的@Autowrired

    使用@RequiredArgsConstructor注解来取代繁琐的@Autowrired

    有了@RequiredArgsConstructor注解,我们就可以减少@Autowired的书写,本文主要介绍了使用@RequiredArgsConstructor注解来取代繁琐的@Autowrired,感兴趣的可以了解一下
    2022-04-04
  • Jmeter入门教程

    Jmeter入门教程

    jmeter是一款优秀的开源性能测试工具,目前最新版本3.0版本,本文给大家介绍Jmeter入门教程,文中通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2021-11-11
  • spring boot整合RabbitMQ(Direct模式)

    spring boot整合RabbitMQ(Direct模式)

    springboot集成RabbitMQ非常简单,如果只是简单的使用配置非常少,springboot提供了spring-boot-starter-amqp项目对消息各种支持。下面通过本文给大家介绍下spring boot整合RabbitMQ(Direct模式),需要的朋友可以参考下
    2017-04-04
  • Spring boot+mybatis+thymeleaf 实现登录注册增删改查功能的示例代码

    Spring boot+mybatis+thymeleaf 实现登录注册增删改查功能的示例代码

    这篇文章主要介绍了Spring boot+mybatis+thymeleaf 实现登录注册增删改查功能的示例代码,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • 基于Process#waitFor()阻塞问题的解决

    基于Process#waitFor()阻塞问题的解决

    这篇文章主要介绍了Process#waitFor()阻塞问题的解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • SpringBoot应用启动内置Tomcat的过程源码分析

    SpringBoot应用启动内置Tomcat的过程源码分析

    这篇文章主要介绍了SpringBoot应用启动内置Tomcat的过程分析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-07-07
  • javaweb前端向后端传值的几种方式总结(附代码)

    javaweb前端向后端传值的几种方式总结(附代码)

    javaweb是java开发中的一个方向,下面这篇文章主要给大家介绍了关于javaweb前端向后端传值的几种方式的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-03-03

最新评论