最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java靜態(tài)方法里使用spring的注入對象方式

 更新時(shí)間:2026年04月24日 09:25:12   作者:單人影i  
本文分析了在使用Spring框架時(shí),靜態(tài)方法中引用非靜態(tài)變量導(dǎo)致空指針的問題,并提出了使用`@PostConstruct`注解、`@Value`注解、構(gòu)造注入和`InitializingBean`接口等解決方案

@Resource 導(dǎo)入應(yīng)用場景

大家都知道,Java靜態(tài)資源(靜態(tài)代碼塊,靜態(tài)方法,靜態(tài)屬性)在類加載的時(shí)候進(jìn)行加載,那么加載時(shí)機(jī)肯定是在spring對象注入之前的,所以我們在調(diào)用實(shí)際的靜態(tài)方法時(shí)就會(huì)出現(xiàn)空指針。

這種可能在實(shí)際開發(fā)中出現(xiàn)在我們的util工具類中.

IDEA編譯報(bào)錯(cuò)原因

  • 靜態(tài)方法里邊引用了非靜態(tài)變量 distributeIdClient,這個(gè)會(huì)直接報(bào)錯(cuò)的

* 應(yīng)該不會(huì)有人認(rèn)為在注入上面加 static 就不會(huì)報(bào)錯(cuò)了吧. QAQ,

  • 靜態(tài)方法中引用的 distributeIdClient 雖然用了@Resource注解,但是該注解的注入是在靜態(tài)方法加載之后執(zhí)行的,所以此處的 distributeIdClient 在使用時(shí)為null
  • 當(dāng)一個(gè)類包含了@Resource的子類時(shí),他就必須交給spring來處理而不能使用new來初始化,否則會(huì)導(dǎo)致他的自動(dòng)裝配的子類為null。所以如果使用注解的方式,那么我們這個(gè)IdWorkerUtils類就需要加上@component注解來交給spring進(jìn)行初始化

解決方案

使用PostConstruct注解 PostConstruct 標(biāo)注方法執(zhí)行時(shí)機(jī)

完成依賴注入以執(zhí)行任何初始化之后,在類投入服務(wù)之前調(diào)用, 即: 在spring項(xiàng)目中,在一個(gè)bean的初始化過程中,方法執(zhí)行先后順序?yàn)?/p>

  • 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服務(wù)獲取請求id,響應(yīng)結(jié)果:{}", JacksonUtil.objectToString(result));
            if (result != null && result.getIsSuccess() && StringUtils.isNotEmpty(result.getData())) {
                return result.getData();
            }
        } catch (Exception e) {
            log.warn("請求id服務(wù)獲取請求id 異常", e);
        }
        return IdWorker.getIdStr();
    }
}

在靜態(tài)方法中 使用@value注解的值

@Component
public class XmlUtils {
	
	//@Value只能給普通變量注入值,不能給靜態(tài)變量賦值,不能直接在這里寫@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;
    }
	 
	 // 注意: 構(gòu)造方法不能 是static 的
    @Value("${xml.encoded:UTF-8}")
    public void setXmlEncoded(String xmlEncoded) {
        XmlUtils.xmlEncoded = xmlEncoded;
    }



    /**
     * @Description: 將 xml 字符串轉(zhuǎn)換成對象
     * @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);
    }


    /**
     * 將對象轉(zhuǎn)換成 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);
            // 去掉默認(rèn)報(bào)文頭
            marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
            // 不進(jìn)行轉(zhuǎn)義字符的處理
            marshaller.setProperty(CharacterEscapeHandler.class.getName(), (CharacterEscapeHandler) (ch, start, length, isAttVal, writer) -> writer.write(ch, start, length));
            StringWriter writer = new StringWriter();
            // 將對象轉(zhuǎn)換成 xml 字符串,存入 writer 中
            marshaller.marshal(obj, writer);
            result = writer.toString();
        } catch (JAXBException e) {
            log.error("將對象轉(zhuǎn)換成xml字符串失敗", e);
        }
        if (StringUtils.isEmpty(result)) {
            throw new RuntimeException(String.format("將 【%s】 類型的對象轉(zhuǎn)換成 xml 文本失敗", clazz.getName()));
        }
        return result;
    }

}

方案解釋

static的變量是歸屬于Class的,而Spring容器上下文只對Java對象進(jìn)行管理,Spring不鼓勵(lì)對static變量做注入Bean的操作,因此如果需要在某些工具類中將Bean賦值給靜態(tài)變量,可以使用構(gòu)造注入的方式. 或者使用@PostConstruct作為橋梁 同@resource. 或者 實(shí)現(xiàn) InitializingBean 重寫 afterPropertiesSet 實(shí)現(xiàn)給靜態(tài)類 賦值

// afterPropertiesSet 示例  容器初始化的時(shí)候給靜態(tài)屬性賦值

@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;
	}
}

調(diào)用過程:@Comment組件在springboot啟動(dòng)的時(shí)候就被掃描到,并且@Value實(shí)現(xiàn)注入,相當(dāng)于將xmlEncoded獲取到的值傳給工具類中的屬性,因此可以在工具類中,直接調(diào)用這個(gè)類的屬性,獲取到@Value取到的值。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

改则县| 蓝山县| 太和县| 安多县| 湘阴县| 宁安市| 鄱阳县| 宜章县| 类乌齐县| 嵊泗县| 弋阳县| 金昌市| 无为县| 高要市| 华阴市| 和政县| 大同县| 都安| 镇沅| 县级市| 高雄市| 重庆市| 浠水县| 宣恩县| 苏尼特左旗| 华亭县| 三河市| 阿拉善左旗| 莒南县| 南平市| 渭源县| 曲阜市| 海盐县| 改则县| 九江市| 洛扎县| 井冈山市| 稷山县| 洞口县| 星子县| 安龙县|