赞
踩
大家都知道,Java静态资源(静态代码块,静态方法,静态属性)在类加载的时候进行加载,那么加载时机肯定是在spring对象注入之前的,所以我们在调用实际的静态方法时就会出现空指针。这种可能在实际开发中出现在我们的util工具类中.
* 应该不会有人认为在注入上面加 static 就不会报错了吧. QAQ,
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(); } }
@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取到的值。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。