当前位置: 代码网 > it编程>编程语言>Java > java静态方法里使用spring的注入对象方式

java静态方法里使用spring的注入对象方式

2026年04月24日 Java 我要评论
@resource 导入应用场景大家都知道,java静态资源(静态代码块,静态方法,静态属性)在类加载的时候进行加载,那么加载时机肯定是在spring对象注入之前的,所以我们在调用实际的静态方法时就会

@resource 导入应用场景

大家都知道,java静态资源(静态代码块,静态方法,静态属性)在类加载的时候进行加载,那么加载时机肯定是在spring对象注入之前的,所以我们在调用实际的静态方法时就会出现空指针。

这种可能在实际开发中出现在我们的util工具类中.

idea编译报错原因

  • 静态方法里边引用了非静态变量 distributeidclient,这个会直接报错的

* 应该不会有人认为在注入上面加 static 就不会报错了吧. qaq,

  • 静态方法中引用的 distributeidclient 虽然用了@resource注解,但是该注解的注入是在静态方法加载之后执行的,所以此处的 distributeidclient 在使用时为null
  • 当一个类包含了@resource的子类时,他就必须交给spring来处理而不能使用new来初始化,否则会导致他的自动装配的子类为null。所以如果使用注解的方式,那么我们这个idworkerutils类就需要加上@component注解来交给spring进行初始化

解决方案

使用postconstruct注解 postconstruct 标注方法执行时机

完成依赖注入以执行任何初始化之后,在类投入服务之前调用, 即: 在spring项目中,在一个bean的初始化过程中,方法执行先后顺序为

  • constructor > @autowired > @postconstruct
import com.baomidou.mybatisplus.core.toolkit.idworker;
import lombok.extern.slf4j.slf4j;
import org.apache.commons.lang3.stringutils;
import org.springframework.stereotype.component;

import javax.annotation.postconstruct;
import javax.annotation.resource;

/**
 * @description: id工具类
 * @author: 单人影
 * @create: 2022-09-15 14:04
 **/
@component
@slf4j
public class idworkerutils {

    private static idworkerutils utils;

    @resource
    private distributeidclient distributeidclient;

    @postconstruct
    public void init() {
        utils = this;
        utils.distributeidclient = this.distributeidclient;
    }

    public static string getid() {
        try {
            result<string> result = utils.distributeidclient.stringnum();
            log.info("请求id服务获取请求id,响应结果:{}", jacksonutil.objecttostring(result));
            if (result != null && result.getissuccess() && stringutils.isnotempty(result.getdata())) {
                return result.getdata();
            }
        } catch (exception e) {
            log.warn("请求id服务获取请求id 异常", e);
        }
        return idworker.getidstr();
    }
}

在静态方法中 使用@value注解的值

@component
public class xmlutils {
	
	//@value只能给普通变量注入值,不能给静态变量赋值,不能直接在这里写@value,这些直接注入就是null
  @value("${xml.encoded:utf-8}")
	public static string xmlencoded;

}

解决办法

/**
 * @description: xml utils
 * @author:  单人影
 * @create: 2022-10-12 10:23
 **/
@slf4j
@component
public class xmlutils {

    private static string xmlencoded;

    public string getxmlencoded() {
        return xmlencoded;
    }
	 
	 // 注意: 构造方法不能 是static 的
    @value("${xml.encoded:utf-8}")
    public void setxmlencoded(string xmlencoded) {
        xmlutils.xmlencoded = xmlencoded;
    }



    /**
     * @description: 将 xml 字符串转换成对象
     * @param: [xmltext, clazz]
     * @return: t
     * @author: 单人影
     * @date: 2022/10/12 10:24
     */
    public static <t> t parsexmlstringtoobj(string xmltext, class<t> clazz) {
        return jaxb.unmarshal(new stringreader(xmltext.trim()), clazz);
    }


    /**
     * 将对象转换成 xml 字符串
     *
     * @param obj   对象
     * @param clazz 对象的类型
     * @return xml 字符串
     */
    public static <t> string parseobjtoxmlstring(t obj, class<t> clazz) {
        string result = stringutils.empty;
        try {
            jaxbcontext jaxbcontext = jaxbcontext.newinstance(obj.getclass());
            marshaller marshaller = jaxbcontext.createmarshaller();
            // 格式化输出
            marshaller.setproperty(marshaller.jaxb_formatted_output, true);
            // 编码格式
            marshaller.setproperty(marshaller.jaxb_encoding, xmlencoded);
            // 去掉默认报文头
            marshaller.setproperty(marshaller.jaxb_fragment, true);
            // 不进行转义字符的处理
            marshaller.setproperty(characterescapehandler.class.getname(), (characterescapehandler) (ch, start, length, isattval, writer) -> writer.write(ch, start, length));
            stringwriter writer = new stringwriter();
            // 将对象转换成 xml 字符串,存入 writer 中
            marshaller.marshal(obj, writer);
            result = writer.tostring();
        } catch (jaxbexception e) {
            log.error("将对象转换成xml字符串失败", e);
        }
        if (stringutils.isempty(result)) {
            throw new runtimeexception(string.format("将 【%s】 类型的对象转换成 xml 文本失败", clazz.getname()));
        }
        return result;
    }

}

方案解释

static的变量是归属于class的,而spring容器上下文只对java对象进行管理,spring不鼓励对static变量做注入bean的操作,因此如果需要在某些工具类中将bean赋值给静态变量,可以使用构造注入的方式. 或者使用@postconstruct作为桥梁 同@resource. 或者 实现 initializingbean 重写 afterpropertiesset 实现给静态类 赋值

// afterpropertiesset 示例  容器初始化的时候给静态属性赋值

@component
public class xmlutils implements initializingbean{
	
	public static string xml_encoded;
	
    @value("${xml.encoded:utf-8}")
	public string xmlencoded;

	@override
	public void afterpropertiesset() throws exception {
		xml_encoded= xmlencoded;
	}
}

调用过程:@comment组件在springboot启动的时候就被扫描到,并且@value实现注入,相当于将xmlencoded获取到的值传给工具类中的属性,因此可以在工具类中,直接调用这个类的属性,获取到@value取到的值。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com