解决在工具类中使用@Autowired为null的问题

解决在工具类中使用@Autowired为null的问题

先说一下开发中遇到的问题

需要使用一个工具类, 但是在工具类的静态方法中无法使用

@Autowired
private LogDataExchangeMapper logDataExchangeMapper;

但是静态方法中不能用这个mapper, 于是我就把工具类的方法改为了非静态(我知道并不合适~).并在外界使用工具类的时候, 先new了一个工具类的对象出来, 再用对象去调用这个方法.

但是很明显, 问题仍然存在
现在虽然在工具类的方法里可以使用logDataExchangeMapper了, 但是获取到的值却为null

因为工具类并没有被spring所管理, spring并不知道我有这个工具类需要自动注入. 所以没办法给我自动注入, 那自然logDataExchangeMapper的值就为null咯, 于是我在工具类的上边加了一个@Component, 把工具类交给spring去管理, 这样spring在自动注入的时候就也会来看一下这个类是否需要自动注入了.

ok, 本以为大功告成, 但是没想到debug了一下发现logDataExchangeMapper的值仍然为null…

于是我上网搜索了一下, 发现在工具类中使用@Autowired是需要做一下改变的, 像这样

@Autowired
    private LogDataExchangeMapper logDataExchangeMapper;

    public static LogDataExcUtil logDataExcUtil;
    @PostConstruct
    public void init() {
        logDataExcUtil = this;
    }

需要先在工具类中加一个本类的成员变量, 再用init()方法去初始化它, 并且在使用mapper的时候需要用logDataExcUtil.logDataExchangeMapper.方法名() 去调用, 而不能直接用logDataExchangeMapper, 这样的话才能得到logDataExchangeMapper的值.

但是为什么呢?为什么只有这样才能得到自动注入的值呢?
我仔细想了一下, 发现, 因为工具类中的方法都是static方法, 而静态方法是跟随类的加载而加载的, 当加载静态方法的时候, spring的@Autowired还没有执行, 所以在调用方法的时候自然就得不到logDataExchangeMapper的值咯.

而上边的代码, 创建了一个静态的本类的成员变量和init()初始化函数, 并在init()方法上加了一个@PostConstruct注解
我们先看一下@PostConstruct的作用

//被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器调用一次,类似于Servlet的inti()方法。
    // 被@PostConstruct修饰的方法会在构造函数之后,init()方法之前运行。
    //应用 PostConstruct 注释的方法必须遵守以下所有标准:该方法不得有任何参数
    //该方法的返回类型必须为 void;该方法不得抛出已检查异常;应用 PostConstruct 的方法可以是 public、protected、package private 或 private;
    // 除了应用程序客户端之外,该方法不能是 static;该方法可以是 final

敲重点!被@PostConstruct修饰的方法会在构造函数之后,init()方法之前运行
也就是说, 在spring项目中,在一个bean的初始化过程中,方法执行先后顺序为

Constructor > @Autowired > @PostConstruct

这样做的目的就是(个人见解哦, 如有错误还请斧正), 延迟本类变量也就是public static LogDataExcUtil logDataExcUtil ;的的这个变量的初始化的时间, 让其在自动注入之后再完成初始化, 这样就能得到userMapper的值了

先执行完构造方法,再注入依赖,最后执行初始化操作,所以这个注解就避免了一些需要在构造方法里使用依赖组件的尴尬

下面附上全部的代码

controller层

LogDataExcUtil logDataExcUtil = new LogDataExcUtil();
        logDataExcUtil.writeExc(jsonObj, xmlString, "41", "0".equals(errorMsg) ? "0" : "1", "0".equals(errorMsg) ? "" : errorMsg, "",subType);

工具类层

package org.jeecg.modules.qyfw.xml.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.hibernate.Hibernate;
import org.jeecg.modules.qyfw.fxfx.controller.FxAnalyseController;
import org.jeecg.modules.qyfw.log.entity.LogDataExchange;
import org.jeecg.modules.qyfw.log.mapper.LogDataExchangeMapper;
import org.jeecg.modules.qyfw.log.service.ILogDataExchangeService;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.sql.rowset.serial.SerialClob;
import java.sql.Clob;
import java.sql.SQLException;
import java.util.*;

@Component
public class LogDataExcUtil {

    @Autowired
    private LogDataExchangeMapperlogDataExchangeMapper;

    public static LogDataExcUtil logDataExcUtil;
    @PostConstruct
    public void init() {
        logDataExcUtil = this;
    }

    public static void writeExc(JSONArray jsonObj, String xmlData, String oper_type, String status, String rst_result, String ids,String subType) throws SQLException {

        LogDataExchange logDataExchange = new LogDataExchange();
        logDataExchange.setSysId(UUID.randomUUID().toString().replaceAll("-", ""));
        logDataExchange.setOperType(oper_type);
        logDataExchange.setStatus(status);
        logDataExchange.setEventType("0");
        logDataExchange.setSubType(subType);
        logDataExchange.setDataCont(xmlData);
//        logDataExchange.setData(new SerialClob(xmlData.toCharArray()));
//        logDataExchange.setDataCont(new SerialClob(xmlData.toCharArray()));
        logDataExchange.setTimestamp(String.valueOf(System.currentTimeMillis()));
        logDataExchange.setLastdate(new Date());
        logDataExcUtil.logDataExchangeMapper.save(logDataExchange);
    }

    
}
  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值