当前位置: 首页 > news >正文

Spring注入静态变量

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

一个类中的非静态成员注入方式非常常见,但有一天我需要写一个工具类,这个工具类中的方法都是静态方法,因此成员必须是静态成员。我用到了Redis查询,获取redis的方法并非静态方法,而是一个spring注入的bean。

如何在静态类(类中的方法都为静态)中,用spring注入静态成员呢?

@Autowired
private static RedisHelperManager redisHelperManager;

这样肯定是不行的!,并且在用到该变量时会抛出运行时异常java.lang.NullPointerException,为什么呢?静态变量不属于对象的属性,属于类属性,spring是基于对象层面的注入。

通过搜索,主要有以下三种实现方式:

  1. 通过setter方法为静态变量注入
  2. @PostConstruct方式注入
  3. @PostConstruct方式的变形

除第3种外,其他都是从网上搜集整理。

通过setter方法为静态变量注入

有人说这是spring官方在意识到对静态变量支持不友好后推出的方式,我并没有找到官方文档,但它却是可以。也是一个最简单且容易理解的方式。

基于注解的方式

将注解放在setter方法之上

@Component
public class DistinctUtil {

    private static RedisHelper redisHelper;

    @Autowired
    public void setRedisHelper(RedisHelper redisHelper) {
        DistinctUtil.redisHelper = redisHelper;
    }

    public static void doDistinct() {
        redisHelper.sdiff();
    }
}

XML配置方式

public class DistinctUtil {

    private static RedisHelper redisHelper;

    public void setRedisHelper(RedisHelper redisHelper) {
        DistinctUtil.redisHelper = redisHelper;
    }

    public static void doDistinct() {
        // 为演示精简代码
        redisHelper.sdiff();
    }
}
<bean class="cn.com.dotleo.DistinctUtil">
        <property name="redisHelper" ref="redisHelper"/>
</bean>

@PostConstruct方式注入

这种方式是我在网上搜到的另一种注入方式,@PostConstruct@PreDestroy 一个是在初始化之后调用,一个是在销毁之前调用。这里用到了@PostConstruct ,在初始化后将一个对象赋值给了该类的静态变量。

基于注解的方式

@Component
public class DistinctUtil {

    @Autowired
    private RedisHelper redisHelper;
    private static DistinctUtil distinctUtil;

    @PostConstruct
    public void init() {
        this.redisHelper = redisHelper;
        distinctUtil = this;

    }

    public static void doDistinct() {
        distinctUtil.redisHelper.sdiff();
    }
}

XML方式

public class DistinctUtil {

    private RedisHelper redisHelper;
    private static DistinctUtil distinctUtil;

    public void init() {
        this.redisHelper = redisHelper;
        distinctUtil = this;

    }

    public static void doDistinct() {
        distinctUtil.redisHelper.sdiff();
    }

    public void setRedisHelper(RedisHelper redisHelper) {
        this.redisHelper = redisHelper;
    }
 <bean class="cn.com.dotleo.DistinctUtil" init-method="init">
        <property name="redisHelper" ref="redisHelper"/>
</bean>

@PostConstruct方式的变形

既然可以在初始化之后赋值,那也必然可以在初始化时赋值,因此想到了第三种方法。

##基于注解的方式

@Component
public class DistinctUtil {

    private static DistinctUtil instance;

    @Autowired
    private RedisHelper redisHelper;

    public DistinctUtil() {
        instance = this;
    }

    public static void doDistinct() {
        // 为演示精简代码
        instance.redisHelper.sdiff();
    }
}

这样,spring注入一个DistinctUtil类,并自动注入RedisHelper,在构造函数中将该类赋值给了静态的成员变量。之后可以通过该成员变量调用注入的redisHelper的方法。

XML配置方式

public class DistinctUtil {

    private static DistinctUtil instance;

    private RedisHelper redisHelper;

    public DistinctUtil(RedisHelper redisHelper) {
        this.redisHelper = redisHelper;
        instance = this;
    }

    public static void doDistinct() {
        // 为演示精简代码
        instance.redisHelper.sdiff();
    }
}
 <bean class="cn.com.dotleo.DistinctUtil">
        <constructor-arg name="redisHelper" ref="redisHelper"/>
 </bean>

Help me

由于本人水平有限,只是从网上搜集方法并记录备忘,如果能帮助到别人非常荣幸。但我并不是很清楚这两类方式(第1种为一类,2、3种为一类)的区别或者优缺点,烦请评论区赐教。

转载于:https://my.oschina.net/u/2930289/blog/1923520

相关文章:

  • Hadoop的hdfs api操作
  • 反射获取枚举的属性注释
  • 各种卷积结构原理及优劣总结
  • linux 程序管理
  • mysql 索引使用教程
  • C#操作MongoDB
  • 分页器(自定制)
  • [转]Linux下防止进程使用swap及防止OOM机制导致进程被kill掉
  • springMVC集成activiti-explorer5.22(一)
  • freebsd为网卡设置别名
  • KVM命令集管理虚拟机
  • ORA-38301:can not perform DDL/DML Over Object in Recycle Bin 11.2.0.4
  • 实验:CentOS下构建私有CA
  • startActivityForResult()的用法(超好用啊)
  • [MongoDB]------windos下的安装部署与基础使用
  • 2017届校招提前批面试回顾
  • docker-consul
  • in typeof instanceof ===这些运算符有什么作用
  • jdbc就是这么简单
  • js面向对象
  • nodejs:开发并发布一个nodejs包
  • PHP CLI应用的调试原理
  • react 代码优化(一) ——事件处理
  • storm drpc实例
  • 从PHP迁移至Golang - 基础篇
  • 从重复到重用
  • 关于 Linux 进程的 UID、EUID、GID 和 EGID
  • 极限编程 (Extreme Programming) - 发布计划 (Release Planning)
  • 简析gRPC client 连接管理
  • 面试遇到的一些题
  • 前端知识点整理(待续)
  • 深入体验bash on windows,在windows上搭建原生的linux开发环境,酷!
  • 通过npm或yarn自动生成vue组件
  • 优化 Vue 项目编译文件大小
  • 源码之下无秘密 ── 做最好的 Netty 源码分析教程
  • 你对linux中grep命令知道多少?
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • 测评:对于写作的人来说,Markdown是你最好的朋友 ...
  • ​ ​Redis(五)主从复制:主从模式介绍、配置、拓扑(一主一从结构、一主多从结构、树形主从结构)、原理(复制过程、​​​​​​​数据同步psync)、总结
  • # Apache SeaTunnel 究竟是什么?
  • # Swust 12th acm 邀请赛# [ K ] 三角形判定 [题解]
  • ###C语言程序设计-----C语言学习(6)#
  • $jQuery 重写Alert样式方法
  • (10)ATF MMU转换表
  • (C#)获取字符编码的类
  • (超详细)2-YOLOV5改进-添加SimAM注意力机制
  • (二)什么是Vite——Vite 和 Webpack 区别(冷启动)
  • (简单) HDU 2612 Find a way,BFS。
  • (十六)一篇文章学会Java的常用API
  • (四)Controller接口控制器详解(三)
  • (四)汇编语言——简单程序
  • (心得)获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。
  • .net core 6 集成和使用 mongodb
  • .net 中viewstate的原理和使用
  • .NET/C# 中设置当发生某个特定异常时进入断点(不借助 Visual Studio 的纯代码实现)