文章目录

  • Spring-利用InitializingBean接口和zookeeper实现项目初始化缓存以及同步监听
  • 1.先贴出几个需要用到的工具类
  • ZkClientUtils
  • WorkerPool
  • IUpdateLocalCacheData
  • RetryRecord
  • Node
  • 2.实现InitializingBean接口的Bean
  • 3.CacheDataSynServerHandle
  • 4.ZkWatcherUtils
  • 5.LoadData
  • 6.spring.xml


Spring-利用InitializingBean接口和zookeeper实现项目初始化缓存以及同步监听

 在我们项目开发过程中,不时需要项目启动初始化一些项目的数据到内存或者缓存中,实现InitializingBean接口达到项目初始化缓存数据,利用zookeeper监听实现数据同步。

1.先贴出几个需要用到的工具类
ZkClientUtils
import com.ithzk.common.PropertiesUtil;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.RetryNTimes;
import org.apache.log4j.Logger;
import org.apache.zookeeper.data.Stat;

import java.util.List;

/**
 * zookeeper客户端工具类
 * @author hzk
 * @date 2018/3/15
 */
public class ZkClientUtils {

    private static final Logger logger = Logger.getLogger(ZkClientUtils.class);

    private CuratorFramework client;

    private String ZK_ADDRESS;

    public ZkClientUtils() {
        ZK_ADDRESS = PropertiesUtil.getValueByBundle("config","zk.address");
        this.client = CuratorFrameworkFactory.newClient(ZK_ADDRESS,new RetryNTimes(10, 5000));
        this.client.start();
    }

    public CuratorFramework getClient(){
        return this.client;
    }

    /**
     * 创建节点
     * @param zkPath 路径
     * @param data 数据
     * @return
     */
    public boolean create(String zkPath,String data){
        try {
            // 如果父节点不存在,则在创建节点的同时创建父节点
            client.create().creatingParentsIfNeeded().forPath(zkPath, data.getBytes("utf-8"));
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("-----  create zk node error:"+e.getMessage());
        }
        return false;
    }

    /**
     * 获取节点值
     * @param zkPath 路径
     * @return
     */
    public String getZnodeData(String zkPath){
        try {
            byte[]  datas = client.getData().forPath(zkPath);
            return new String(datas,"utf-8");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("----- get zk node data error:"+e.getMessage());
        }
        return null;
    }

    /**
     * 设置节点值
     * @param zkPath 路径
     * @param data 数据
     * @return
     */
    public boolean set(String zkPath,String data){
        try {
            if(isExists(zkPath)){
                client.setData().forPath(zkPath, data.getBytes("utf-8"));
            }else {
                create(zkPath, data);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("----- set zk node data error:"+e.getMessage());
        }
        return false;
    }

    /**
     * 检验节点是否存在
     * @param zkPath 路径
     * @return
     * @throws Exception
     */
    public boolean isExists(String zkPath) throws Exception{
        Stat stat = client.checkExists().forPath(zkPath);
        return null != stat;
    }

    /**
     * 获取子节点列表
     * @param zkPath 路径
     * @return
     */
    public List<String> list(String zkPath){
        try {
            return client.getChildren().forPath(zkPath);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("-----  get zk children node list error:"+e.getMessage());
        }
        return null;
    }
    public void close(){
        client.close();
    }

}
WorkerPool
import java.util.concurrent.*;

public class WorkerPool {

	/**
	 * 线程池执行任务
	 * @param command
	 */
	public void exec(Runnable command){
		ThreadFactory threadFactory = Executors.defaultThreadFactory();
		ArrayBlockingQueue queue = new ArrayBlockingQueue<Runnable>(2);
        ThreadPoolExecutor executorPool = new ThreadPoolExecutor(2, 4, 10, TimeUnit.SECONDS, queue, threadFactory);
        executorPool.execute(command);
	}
}
IUpdateLocalCacheData
/**
 * @author hzk
 * @date 2018/3/15
 */
public interface IUpdateLocalCacheData {

    void change(Node node);
}
RetryRecord
/**
 * 缓存重试统计类
 * @author hzk
 * @date 2018/3/16
 */
public class RetryRecord {

    private String lastRecordTime;

    private Integer retryCount;

    public RetryRecord(String lastRecordTime, Integer retryCount) {
        this.lastRecordTime = lastRecordTime;
        this.retryCount = retryCount;
    }

    public String getLastRecordTime() {
        return lastRecordTime;
    }

    public void setLastRecordTime(String lastRecordTime) {
        this.lastRecordTime = lastRecordTime;
    }

    public Integer getRetryCount() {
        return retryCount;
    }

    public void setRetryCount(Integer retryCount) {
        this.retryCount = retryCount;
    }
}
Node
public class Node {
	private String path;
	private String data;
	
	public Node(String path,String data) {
		this.path = path;
		this.data = data;
	}
	public Node() {
	}
	
	public String getPath() {
		return path;
	}
	public void setPath(String path) {
		this.path = path;
	}
	public String getData() {
		return data;
	}
	public void setData(String data) {
		this.data = data;
	}
	@Override
	public String toString() {
		return "Node [path=" + path + ", data=" + data + "]";
	}
	
	
}
2.实现InitializingBean接口的Bean
package com.ithzk.common.listener;

import com.ithzk.common.zk.CacheDataSynServerHandle;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.web.context.ServletContextAware;

import javax.servlet.ServletContext;

/**
 * @author hzk
 * @date 2018/3/15
 */
public class InitDataListener implements InitializingBean,ServletContextAware {

    private static final Logger logger = Logger.getLogger(InitDataListener.class);

    public static ServletContext servletContext;

    @Override
    public void setServletContext(ServletContext arg0) {
        InitDataListener.servletContext = arg0;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        //初始化数据 加载数据到本地缓存
        logger.info("----------------- init cache data.. -----------------------");
        new CacheDataSynServerHandle().loadLocal();

        //注册zk监听节点变化 同步数据
        new CacheDataSynServerHandle().start();
        logger.info("----------------- init cache data complete -----------------------");
    }
}
3.CacheDataSynServerHandle
import com.ithzk.common.BeanFactoryUtil;
import com.ithzk.common.Constants;
import com.ithzk.common.JsonUtil;
import com.ithzk.common.PropertiesUtil;
import com.ithzk.common.dic.LoadData;
import com.ithzk.common.zk.ifc.IUpdateLocalCacheData;
import com.ithzk.dto.out.BaseResponse;
import com.ithzk.dto.out.DictionaryResponse;
import com.ithzk.dto.out.PartnerResponse;
import com.ithzk.ifc.DictionaryIfc;
import com.ithzk.ifc.PartnerIfc;
import com.ithzk.common.Detect;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 服务端初始化缓存数据 同步缓存数据
 * @author hzk
 * @date 2018/3/15
 */
@Component
public class CacheDataSynServerHandle {

    private static final Logger logger = Logger.getLogger(CacheDataSynServerHandle.class);

    private String ZK_ADDRESS;

    /**
     * 初始化CacheDataSynServerHandle
     */
    public void start(){
        new WorkerPool().exec(new Runnable() {

            @Override
            public void run() {
                new CacheDataSynServerHandle().init();
            }
        });
    }

    /**
     * 注册监听
     */
    public void init() {
        ZK_ADDRESS = PropertiesUtil.getValueByBundle("config","zk.address");
        logger.info("------register watch path:"+ZK_ADDRESS);
        //添加监听
        ZkWatcherUtils zkWatcherUtils = new ZkWatcherUtils();
        try {
            UpdateLocalCacheData change = new UpdateLocalCacheData();
            zkWatcherUtils.addWatch(Constants.AbstractZkNodePath.ZK_DICTIONRAY_PATH,change);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("------register watch error :"+e.getMessage());
        }

        loadZKData();
    }

    /**
     * 检查zk中是否有数据
     * 没有则初始化zk字典数据
     */
    private void loadZKData(){
        ZkClientUtils zkClientUtils = new ZkClientUtils();
        try {
            if(!zkClientUtils.isExists(Constants.AbstractZkNodePath.ZK_DICTIONRAY_PATH)){
                List<DictionaryResponse> dicData = getDicData();
                String data = JsonUtil.list2json(dicData);
                zkClientUtils.create(Constants.AbstractZkNodePath.ZK_DICTIONRAY_PATH, data);
                logger.info("------loadZKData success!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("------loadZKData fail msg:"+e.getMessage());
        }finally{
            zkClientUtils.close();
        }
    }

    /**
     * 加载本地缓存
     */
    public void loadLocal(){
        try {
            logger.info("------loadLocal dictionary data--");
            List<DictionaryResponse> dataDic = getDicData();
            List<PartnerResponse> partnerDic = getPartnerData();
            new UpdateLocalCacheData().convert(dataDic,partnerDic);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("-------------- loadLocal error :"+e.getMessage());
        }
    }

    /**
     * 重新加载本地缓存
     */
    public void reloadLocal() {
        loadLocal();
    }

    /**
     * 获得字典数据
     * @return
     */
    private static List<DictionaryResponse> getDicData() {
        DictionaryIfc dictionaryIfc = BeanFactoryUtil.getInstance("dictionaryIfc");
        Map<String, Object> conditions = new HashMap<String, Object>();
        BaseResponse<List<DictionaryResponse>> listBaseResponseDic = dictionaryIfc.selectByExample(conditions);
        List<DictionaryResponse> dicList = listBaseResponseDic.getDatat();
        return dicList;
    }

    /**
     * 获得合作方数据
     * @return
     */
    private static List<PartnerResponse> getPartnerData() {
        PartnerIfc partnerIfc = BeanFactoryUtil.getInstance("partnerIfc");
        Map<String, Object> conditions = new HashMap<String, Object>();
        BaseResponse<List<PartnerResponse>> listBaseResponsePartner = partnerIfc.selectByExample(conditions);
        List<PartnerResponse> partnerList = listBaseResponsePartner.getDatat();
        return partnerList;
    }


    static class UpdateLocalCacheData implements IUpdateLocalCacheData {

        @Override
        public void change(Node node) {
            try {
                logger.info("-------------- zookeeper node change -------------");
                List<DictionaryResponse> dataDic = getDicData();
                List<PartnerResponse> partnerDic = getPartnerData();
                convert(dataDic,partnerDic);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("-------------- zookeeper node change error :"+e.getMessage());
            }
        }

        public void convert(List<DictionaryResponse> dataDic,List<PartnerResponse> partnerDic){
            if(!Detect.notEmpty(dataDic)){
                return;
            }
            try {
                LoadData.buildLocalCache(dataDic,partnerDic);
                logger.info("-------------- server start update local data.... ---------------------");
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("-------------- loadLocal error :"+e.getMessage());
            }
        }

    }
}
4.ZkWatcherUtils
import com.ithzk.common.PropertiesUtil;
import com.ithzk.common.zk.ifc.IUpdateLocalCacheData;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.NodeCache;
import org.apache.curator.framework.recipes.cache.NodeCacheListener;
import org.apache.curator.retry.RetryNTimes;
import org.apache.log4j.Logger;

/**
 * zookeeper监听工具类
 * @author hzk
 * @date 2018/3/15
 */
public class ZkWatcherUtils {

    private static final Logger logger = Logger.getLogger(ZkWatcherUtils.class);

    private String ZK_ADDRESS;

    /**
     * 添加监听事件
     * @param zkPath 路径
     * @param updateLocalCacheData 回调
     * @throws Exception
     */
    public void addWatch(String zkPath,final IUpdateLocalCacheData updateLocalCacheData) throws Exception {
        // 连接zk
        ZK_ADDRESS = PropertiesUtil.getValueByBundle("config","zk.address");
        CuratorFramework client = CuratorFrameworkFactory.newClient(ZK_ADDRESS, new RetryNTimes(10, 5000) );
        client.start();
        logger.info("-----  zk client start success ------");

        //注册监听
        final NodeCache watcher = new NodeCache(client, zkPath);
        watcher.getListenable().addListener(new NodeCacheListener() {
            @Override
            public void nodeChanged() throws Exception {
                if(null != watcher.getCurrentData()){
                    if(null != updateLocalCacheData){
                        Node node = new Node(watcher.getCurrentData().getPath(),new String(watcher.getCurrentData().getData(),"utf-8"));
                        updateLocalCacheData.change(node);
                    }
                    logger.info("-----  zk node changed, data is: "+ new String(watcher.getCurrentData().getData(),"utf-8"));
                }else{
                    logger.error("-----  Node changed, data is null -----");
                }
            }
        });

        watcher.start(true);
        logger.error("-----  Register zk watcher success! -----");
    }

}
5.LoadData
package com.blog.cas.common.dic;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.blog.cas.common.constants.Constants;
import com.blog.cas.common.utils.BeanFactoryUtils;
import com.blog.cas.common.utils.Detect;
import com.blog.cas.common.utils.json.JsonUtils;
import com.blog.cas.common.zk.CacheDataSynServerHandle;
import com.blog.cas.common.zk.RetryRecord;
import com.blog.cas.common.zk.ZkClientUtils;
import com.blog.cas.repository.entity.BlogDictionary;
import com.blog.cas.service.IDictionaryService;
import org.apache.log4j.Logger;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 本地缓存操作类
 * @author hzk
 * @date 2018/11/14
 */
public class LoadData {
	
	private static final Logger logger = Logger.getLogger(LoadData.class);

	/**
	 * itemKey value
	 */
	private static Map<String, BlogDictionary> dicInfoMap = new HashMap<>();

	/**
	 * Id value
	 */
	private static Map<Integer, BlogDictionary> dicInfoIdMap = new HashMap<>();

	private static ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
	private static Lock r = rwl.readLock();
	private static Lock w = rwl.writeLock();

    /*------------------------------------------ mysql select-------------------------------------------*/

	/**
	 * 通过itemKey从数据库中查询数据
	 * @param key
	 * @return {@link BlogDictionary}
	 */
	private static BlogDictionary getDicByItemKeyWithIfc(String key){
		IDictionaryService blogDictionaryService = BeanFactoryUtils.getInstance("dictionaryService");
		return blogDictionaryService.selectByItemKey(key);
	}

	/**
	 * 通过id从数据库中查询数据
	 * @param id
	 * @return {@link BlogDictionary}
	 */
	private static BlogDictionary getDicByIdWithIfc(Integer id){
		IDictionaryService blogDictionaryService= BeanFactoryUtils.getInstance("dictionaryService");
		return blogDictionaryService.selectByPrimaryKey(id);
	}

    /*------------------------------------------by itemKey-------------------------------------------*/
	/**
	 * 通过itemKey查询字典
	 * @param key
	 * @return {@link BlogDictionary}
	 */
	public static BlogDictionary getDicByItemKey(String key) {
		r.lock();
		try {
			BlogDictionary dictionary = dicInfoMap.get(key);
			if (dictionary != null) {
				return dictionary;
			}
			retryBuildLocalCache(dicInfoMap);
			BlogDictionary dicByItemKeyWithIfc = getDicByItemKeyWithIfc(key);
			if(null != dicByItemKeyWithIfc){
				return dicByItemKeyWithIfc;
			}
			logger.warn("======Not Found Dic key:" + key);
			return null;
		}finally {
			r.unlock();
		}

	}

	/**
	 * 通过itemKey查询字典value
	 * @param key 字典key
	 * @param check 是否验证启用
	 * @return
	 */
	public static String getDicValueByItemKey(String key,boolean check) {
		r.lock();
		try {
			BlogDictionary dictionary = dicInfoMap.get(key);
			if (dictionary != null) {
				if(check){
					if(Detect.equal(LoadData.getDicIdByItemKey(Constants.AbstractPublicStatus.ENABLE),dictionary.getFrState())){
						return dictionary.getItemValue();
					}else{
						return null;
					}
				}else{
					return dictionary.getItemValue();
				}
			}
			retryBuildLocalCache(dicInfoMap);
			BlogDictionary dicByItemKeyWithIfc = getDicByItemKeyWithIfc(key);
			if(null != dicByItemKeyWithIfc){
				if(check){
					if(Detect.equal(LoadData.getDicIdByItemKey(Constants.AbstractPublicStatus.ENABLE),dicByItemKeyWithIfc.getFrState())){
						return dicByItemKeyWithIfc.getItemValue();
					}else{
						return null;
					}
				}else{
					return dicByItemKeyWithIfc.getItemValue();
				}
			}
			logger.warn("======Not Found Dic key:" + key);
			return null;
		}finally {
			r.unlock();
		}

	}

	/**
	 * 通过itemKey查询字典value
	 * @param key 字典key
	 * @param defaultValue 不存在时设置默认值
	 * @return
	 */
	public static String getDicValueByItemKey(String key,String defaultValue){
		r.lock();
		try {
			BlogDictionary dictionary = dicInfoMap.get(key);
			if (dictionary != null) {
				return dictionary.getItemValue();
			}
			retryBuildLocalCache(dicInfoMap);
			BlogDictionary dicByItemKeyWithIfc = getDicByItemKeyWithIfc(key);
			if(null != dicByItemKeyWithIfc){
				return dicByItemKeyWithIfc.getItemValue();
			}
			logger.warn("======Not Found Dic key:" + key);
			return defaultValue;
		} finally {
			r.unlock();
		}
	}

	/**
	 * 通过itemKey查询字典ID
	 * @param key 字典key
	 * @return
	 */
	public static int getDicIdByItemKey(String key) {
		r.lock();
		try {
			BlogDictionary dictionary = dicInfoMap.get(key);
			if (dictionary != null) {
				return Detect.asPrimitiveInt(dictionary.getId());
			}
			retryBuildLocalCache(dicInfoMap);
			BlogDictionary dicByItemKeyWithIfc = getDicByItemKeyWithIfc(key);
			if(null != dicByItemKeyWithIfc){
				return dicByItemKeyWithIfc.getId();
			}
			logger.warn("======Not Found Dic key:" + key);
			return 0;
		}finally {
			r.unlock();
		}
	}

	/**
	 * 通过itemKey查询字典中文名称
	 * @param key 字典key
	 * @return
	 */
	public static String getDicNameByItemKey(String key) {
		r.lock();
		try {
			BlogDictionary dictionary = dicInfoMap.get(key);
			if (dictionary != null) {
				return Detect.asString(dictionary.getItemNamecn());
			}
			retryBuildLocalCache(dicInfoMap);
			BlogDictionary dicByItemKeyWithIfc = getDicByItemKeyWithIfc(key);
			if(null != dicByItemKeyWithIfc){
				return dicByItemKeyWithIfc.getItemNamecn();
			}
			logger.warn("======Not Found Dic key:" + key);
			return null;
		}finally {
			r.unlock();
		}
	}

    /*------------------------------------------by id-------------------------------------------*/
	/**
	 * 通过ID查询字典
	 * @param id 字典ID
	 * @return {@link BlogDictionary}
	 */
	public static BlogDictionary getDicById(Integer id) {
		r.lock();
		try {
			BlogDictionary dictionary = dicInfoIdMap.get(id);
			if (dictionary != null) {
				return dictionary;
			} else{
				retryBuildLocalCache(dicInfoIdMap);
				BlogDictionary dicByItemKeyWithIfc = getDicByIdWithIfc(id);
				if(null != dicByItemKeyWithIfc){
					return dicByItemKeyWithIfc;
				}
				logger.warn("======Not Found Dic id:" + id);
				return null;
			}
		}finally {
			r.unlock();
		}
	}

	/**
	 * 通过id查询字典value
	 * @param id 字典ID
	 * @return
	 */
	public static String getDicValueById(Integer id) {
		r.lock();
		try {
			BlogDictionary dictionary = dicInfoIdMap.get(id);
			if (dictionary != null) {
				return dictionary.getItemValue();
			} else{
				retryBuildLocalCache(dicInfoIdMap);
				BlogDictionary dicByItemKeyWithIfc = getDicByIdWithIfc(id);
				if(null != dicByItemKeyWithIfc){
					return dicByItemKeyWithIfc.getItemValue();
				}
				logger.warn("======Not Found Dic id:" + id);
				return null;
			}
		}finally {
			r.unlock();
		}
	}

	/**
	 * 通过ID查询字典itemKey
	 * @param id 字典ID
	 * @return
	 */
	public static String getDicItemKeyById(Integer id) {
		r.lock();
		try {
			BlogDictionary dictionary = dicInfoIdMap.get(id);
			if (dictionary != null) {
				return Detect.asString(dictionary.getItemKey());
			} else {
				retryBuildLocalCache(dicInfoIdMap);
				BlogDictionary dicByItemKeyWithIfc = getDicByIdWithIfc(id);
				if(null != dicByItemKeyWithIfc){
					return dicByItemKeyWithIfc.getItemKey();
				}
				logger.warn("======Not Found Dic id:" + id);
				return null;
			}
		}finally {
			r.unlock();
		}
	}

	/**
	 * 通过ID查询字典parentId
	 * @param id 字典ID
	 * @return
	 */
	public static Integer getDicParentIdById(Integer id) {
		r.lock();
		try {
			BlogDictionary dictionary = dicInfoIdMap.get(id);
			if (dictionary != null) {
				return dictionary.getParentId();
			} else {
				retryBuildLocalCache(dicInfoIdMap);
				BlogDictionary dicByItemKeyWithIfc = getDicByIdWithIfc(id);
				if(null != dicByItemKeyWithIfc){
					return dicByItemKeyWithIfc.getParentId();
				}
				logger.warn("======Not Found Dic id:" + id);
				return null;
			}
		}finally {
			r.unlock();
		}
	}

	/**
	 * 通过ID查询字典中文名称
	 * @param id 字典ID
	 * @return
	 */
	public static String getDicNameById(Integer id) {
		r.lock();
		try {
			BlogDictionary dictionary = dicInfoIdMap.get(id);
			if (dictionary != null) {
				return Detect.asString(dictionary.getItemNamecn());
			} else {
				retryBuildLocalCache(dicInfoIdMap);
				BlogDictionary dicByItemKeyWithIfc = getDicByIdWithIfc(id);
				if(null != dicByItemKeyWithIfc){
					return dicByItemKeyWithIfc.getItemNamecn();
				}
				logger.warn("======Not Found Dic id:" + id);
				return null;
			}
		}finally {
			r.unlock();
		}
	}

    /*------------------------------------------init data-------------------------------------------*/

	/**
	 * 初始化内存数据
	 * 字典/合作方
	 */
	public static void buildLocalCache(List<BlogDictionary> dataDic){
		w.lock();
		try {
			//初始化数据字典
			logger.warn("-------------------init dictionary start...---------------------");
			for (BlogDictionary blogDictionary : dataDic) {
				dicInfoMap.put(Detect.trim(blogDictionary.getItemKey()), blogDictionary);
				dicInfoIdMap.put(blogDictionary.getId(), blogDictionary);
			}
			logger.warn("-------------------init dictionary complete---------------------");
		} catch (Exception e){
			e.printStackTrace();
			logger.warn("-------------------init LoadData error---------------------"+e.getMessage());
		} finally{
			w.unlock();
		}
	}

	/**
	 * 重试机制
	 * 若多次发现本地缓存为空 则重新加载本地数据
	 */
	private static void retryBuildLocalCache(Map<?,BlogDictionary> dataDic){
		// 内存中数据为null时 记录获取次数 到达一定次数尝试重试加载缓存
		if(!Detect.notEmpty(dataDic)){
			logger.warn("------ local cache dic is null -------");
			ZkClientUtils zkClientUtils = new ZkClientUtils();
			Date currentDate = new Date(System.currentTimeMillis());
			try {
				if(!zkClientUtils.isExists(Constants.AbstractZkNodePath.ZK_RETRY_RECORD_PATH)){
					logger.info("------ init retry record start... -------");
					RetryRecord retryRecord = new RetryRecord(Detect.asString(currentDate.getTime()),0);
					String data = JsonUtils.object2json(retryRecord);
					zkClientUtils.create(Constants.AbstractZkNodePath.ZK_RETRY_RECORD_PATH, data);
					logger.info("------ init retry record success -------");
				}
				String znodeData = zkClientUtils.getZnodeData(Constants.AbstractZkNodePath.ZK_RETRY_RECORD_PATH);
				RetryRecord retryRecord = JSONObject.toJavaObject(JSON.parseObject(znodeData), RetryRecord.class);
				if(null != retryRecord){
					Integer retryCount = retryRecord.getRetryCount();
					if(null != retryCount){
						if(retryCount % Constants.AbstractZkNodePath.ZK_RETRY_COUNT_REGEX == 1){
							// 尝试重新加载本地缓存
							new CacheDataSynServerHandle().reloadLocal();
						}
						retryRecord.setLastRecordTime(Detect.asString(currentDate.getTime()));
						retryRecord.setRetryCount(retryCount+1);
						String data = JsonUtils.object2json(retryRecord);
						zkClientUtils.set(Constants.AbstractZkNodePath.ZK_RETRY_RECORD_PATH, data);
					}

				}
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("------ retry build local cache fail msg:"+e.getMessage());
			}finally{
				zkClientUtils.close();
			}
		}
	}

	/**
	 * 刷新zk字典节点缓存
	 * @return
	 */
	public static int renovateZkDicCache(){
		ZkClientUtils zkClientUtils = new ZkClientUtils();
		int success = 1;
		w.lock();
		try {
			List<BlogDictionary> blogDictionary = CacheDataSynServerHandle.getDicData();
			String data = JsonUtils.list2json(blogDictionary);
			if(!zkClientUtils.isExists(Constants.AbstractZkNodePath.ZK_DICTIONRAY_PATH)){
				zkClientUtils.create(Constants.AbstractZkNodePath.ZK_DICTIONRAY_PATH, data);
				logger.info("------renovateZKData success!");
			}else{
				zkClientUtils.set(Constants.AbstractZkNodePath.ZK_DICTIONRAY_PATH, data);
				logger.info("------renovateZKData success!");
			}
		} catch (Exception e) {
			e.printStackTrace();
			success = 0;
			logger.error("------renovateZKData fail msg:"+e.getMessage());
		}finally{
			zkClientUtils.close();
			w.unlock();
		}
		return success;
	}

}
6.spring.xml

 将laze-init设为false,启动即会加载

<!-- spring系统启动以后,会先加载该类 -->
	<bean id="beanFactoryUtil" class="com.ithzk.common.BeanFactoryUtil" lazy-init="false"/>
	<bean id="initDataListener" class="com.ithzk.common.listener.InitDataListener" lazy-init="false"/>