静态方法调用spring注入的service类问题

问题:1.在静态方法中调用@Autowired或@Resource注解的Spring注入的service的方法问题。

分析:1.首先,静态方法中不可调用非静态方法,这与JVM加载类的机制有关。

   2.spring自动注入,使用spring框架的很常用如果在静态方法中调用此注入类的方法,发现注入为'null';原因不是spring未注入,而是被static方法给'清空'了。

解决方法一:

0      @Component //此处注解不能省却(0)
 1      public class NtClient {
 2      /** 
 3         * 日志 
 4         */ 
 5         private static String clazzName = NtClient.class.getName(); 
 6          /** 
 7             * 此处是要使用的service需要spring注入(1) 
 8             */ 
 9          @Autowired 
10           private NotifyTimeService notifyTimeService; 
11           private static NtClient ntClient; 
12           /** 
13              * 注意此处注解(2) */
14           @PostConstruct  
15           public void init() {       
16                    ntClient = this; 
17                    ntClient.notifyTimeService = this.notifyTimeService; 
18            } 
19             /** 
20                * 主要使用场景(3) 
21                */ 
22            public static void insertParam(int id){ 
23                    /** 
24                       * 注意此处的调用方法(4) 
25                       */    
26                   if(ntClient.notifyTimeService.deleteNotifyTime(id)){
27                   }
28            }
29 }    

注释:(0)处作用是将(2)ntClient = this;this进行赋值(注:如果无注解ntClient 将null)     (1)处为spring自动注入,使用spring框架的很常用,但是如果在静态方法中调用此注入类的方法,发现注入为'null';原因不是spring未注入,而是被static方法给'清空'了,在无法先于static方法初始化之前想了一个办法    (2)处为想到的办法:通过(注:@PostConstruct修饰的方法会在服务器加载Servle的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行。PreDestroy()方法在destroy()方法执行执行之后执行)的方法public void init()先给该类赋值,然后通过(1)出注入进来。这样不影响dao等service下面调用的注入!    (3)处要处理的特殊方法static(经典是 main()方法,自己想想基础,它里面可以使用的方法调用的模式)    (4)处是使用这样模式的调用方式notifyTimeService现在是作为ntClient的属性

   

上面的解决方法是查看别人的,确实可以,感谢博主。

解决方法二:

      出现这种问题的场景多是操作数据库,注入的service中的方法调用dao层造成。

      这里给出最笨的一种方法,写一个Util,里面写静态方法,用原生的JDBC去操作库,在静态方法类中不用注入,直接调用该静态方法即可。

      下面给出部分JDBC操作数据库代码:

package com.zichen.xhkq.util;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.zichen.xhkq.pojo.weixin.Wechat;

/**
 * 
 * 项目名称:weChatJavaTokenValidate 类名称:WeChatUtil 类描述: 从数据库读取wechat 的类 创建人:xpz
 * 创建时间:2018/7/16 下午2:00:13 修改人: 修改时间:2018/7/16 下午2:00:13 修改备注:
 * 
 * @version
 */
@Service
public class WeChatUtil {

	private static Logger log = LoggerFactory.getLogger(WeChatUtil.class);

	/**
	 * 
	 * @Title: getTokenFromDB
	 * @Description: TODO(从数据库里面获取token,id=1)
	 * @param @return
	 * @return Map<String,Object>
	 * @throws
	 */
	public static Wechat getWeChatFromDB(int schoolId) {

		log.info("开始进入数据库获取Wechat");
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		// 查询schoolId的数据
		String c = "select * from wechat_token_h where schoolId = " + schoolId;

		Wechat wechat = new Wechat();
		try {
			// 创建数据库链接
			con = DBUtility.getConnection();
			// 创建处理器
			stmt = con.prepareStatement(c);
			// 查询Token,读取1条记录
			rs = stmt.executeQuery();
			if (rs.next()) {

				wechat.setAppid(rs.getString("appid"));
				wechat.setAppsecret(rs.getString("appsecret"));
				wechat.setToken(rs.getString("token"));
				// wechat.setSchoolId(rs.getString("schoolId"));

			}

		} catch (SQLException ex) {
			System.out.println("获取token的数据库操作异常:" + ex.getMessage());
		} finally {
			DBUtility.closeConnection(con);
		}
		log.info("获取wechat的数据库查完了返回" + wechat.toString());
		return wechat;
	}

}

JDBC工具类

package com.zichen.xhkq.util;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

import org.apache.commons.dbcp.BasicDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 
 * 项目名称:weChatJavaTokenValidate   
 * 类名称:DBUtility   
 * 类描述:   连接数据库工具类
 * 创建人:lk
 * 创建时间:2017-11-28 下午6:59:14   
 * 修改人:   
 * 修改时间:2017-11-28 下午6:59:14   
 * 修改备注:   
 * @version
 */
public class DBUtility {
    private static BasicDataSource dataSource = null;
    private static Logger log = LoggerFactory.getLogger(CommonUtil.class);
    public DBUtility() {
    }

    public static void init() {

        Properties dbProps = new Properties();
        // 取配置文件可以根据实际的不同修改
        try {
        	log.info("获取配置文件中的数据库配置");
            dbProps.load(DBUtility.class.getClassLoader().getResourceAsStream("jdbc.properties"));
            log.info("获取配置文件中的数据库配置完成");
        } catch (IOException e) {
            e.printStackTrace();
            log.info("获取配置文件中的数据库配置出现异常");
        }

        try {
        	 log.info("获取配置文件中的数据库配置中各属性及值");
            String driveClassName = dbProps.getProperty("driverClassName");
            String url = dbProps.getProperty("url");
            String username = dbProps.getProperty("username");
            String password = dbProps.getProperty("password");

            String initialSize = dbProps.getProperty("initialSize");
            String minIdle = dbProps.getProperty("minIdle");
            String maxIdle = dbProps.getProperty("maxIdle");
            String maxWait = dbProps.getProperty("maxWait");
            String maxActive = dbProps.getProperty("maxActive");

            dataSource = new BasicDataSource();
            dataSource.setDriverClassName(driveClassName);
            dataSource.setUrl(url);
            dataSource.setUsername(username);
            dataSource.setPassword(password);

            // 初始化连接数
            if (initialSize != null)
                dataSource.setInitialSize(Integer.parseInt(initialSize));

            // 最小空闲连接
            if (minIdle != null)
                dataSource.setMinIdle(Integer.parseInt(minIdle));

            // 最大空闲连接
            if (maxIdle != null)
                dataSource.setMaxIdle(Integer.parseInt(maxIdle));

            // 超时回收时间(以毫秒为单位)
            if (maxWait != null)
                dataSource.setMaxWait(Long.parseLong(maxWait));

            // 最大连接数
            if (maxActive != null) {
                if (!maxActive.trim().equals("0"))
                    dataSource.setMaxActive(Integer.parseInt(maxActive));
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("创建连接池失败!请检查设置!!!");
            log.info("创建连接池失败!请检查设置!!!log");
        }
    }

    /**
     * 数据库连接
     * 
     * @return
     * @throws SQLException
     */
    public static synchronized Connection getConnection() throws SQLException {
        if (dataSource == null) {
            init();
        }
        Connection conn = null;
        if (dataSource != null) {

        	conn = dataSource.getConnection();
        }
        return conn;
    }

    /**
     * 关闭数据库
     * 
     * @param conn
     */
    public static void closeConnection(Connection conn) {
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                System.out.println("关闭资源失败");
                e.printStackTrace();
            }
        }
    }

}

JDBC配置文件jdbc.properties

driverClassName=com.mysql.jdbc.Driver
url=jdbc\:mysql\://localhost\:330
username=
password=
#配置监控统计拦截的filters
filters=stat
#定义初始连接�?
initialSize=10
#定义�?��连接�?
maxActive=300
#定义�?��空闲
maxIdle=20
#定义�?��空闲
minIdle=1
#定义�?��等待时间
maxWait=60000
#配置间隔多久才进行一次检测,�?���?��关闭的空闲连接,单位是毫�?
timeBetweenEvictionRunsMillis=60000
#配置�?��连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis=300000
validationQuery=SELECT 1
testWhileIdle=true
testOnBorrow=false
testOnReturn=false
poolPreparedStatements=false
maxPoolPreparedStatementPerConnectionSize=200

  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值