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

/**
 * 加载数据到内存
 * @author hzk
 * @date 2018/3/15
 */
public class LoadData{

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

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

    /**
     * Id value
     */
    public static Map<Integer, DictionaryResponse> dicInfoIsMap = new HashMap<Integer, DictionaryResponse>();

    /**
     * 合作方数据
     */
    public static Map<Integer, PartnerResponse> parInfoIsMap = new HashMap<Integer, PartnerResponse>();

    /**
     * 直播频道数据
     */
    public static Map<Integer, LiveAisleResponse> liveInfoIsMap = new HashMap<Integer, LiveAisleResponse>();

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

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

    /**
     * 通过itemKey从数据库中查询数据
     * @param key
     * @return
     */
    private static DictionaryResponse getDicByItemKeyWithIfc(String key){
        DictionaryIfc dictionaryIfc = BeanFactoryUtil.getInstance("dictionaryIfc");
        BaseResponse<DictionaryResponse> dictionaryResponseBaseResponse = dictionaryIfc.selectByItemKey(key);
        DictionaryResponse dic = dictionaryResponseBaseResponse.getDatat();
        return dic;
    }

    /**
     * 通过id从数据库中查询数据
     * @param id
     * @return
     */
    private static DictionaryResponse getDicByIdWithIfc(Integer id){
        DictionaryIfc dictionaryIfc = BeanFactoryUtil.getInstance("dictionaryIfc");
        BaseResponse<DictionaryResponse> dictionaryResponseBaseResponse = dictionaryIfc.selectByPrimaryKey(id);
        DictionaryResponse dic = dictionaryResponseBaseResponse.getDatat();
        return dic;
    }

    /**
     * 通过id从数据库中查询合作方
     * @param id
     * @return
     */
    private static PartnerResponse getPartnerByIdWithIfc(Integer id){
        PartnerIfc partnerIfc = BeanFactoryUtil.getInstance("partnerIfc");
        BaseResponse<PartnerResponse> dictionaryResponseBaseResponse = partnerIfc.selectByPrimaryKey(id);
        PartnerResponse partner = dictionaryResponseBaseResponse.getDatat();
        return partner;
    }

    /**
     * 通过id从数据库中查询直播频道
     * @param id
     * @return
     */
    private static LiveAisleResponse getLiveAisleByIdWithIfc(Integer id){
        LiveAisleIfc liveAisleIfc = BeanFactoryUtil.getInstance("liveAisleIfc");
        BaseResponse<LiveAisleResponse> liveAisleResponseBaseResponse = liveAisleIfc.selectByPrimaryKey(id);
        LiveAisleResponse liveAisle = liveAisleResponseBaseResponse.getDatat();
        return liveAisle;
    }


    /*------------------------------------------by itemKey-------------------------------------------*/
    /**
     * 通过itemKey查询字典
     * @param key
     * @return
     */
    public static DictionaryResponse getDicByItemKey(String key) {
        r.lock();
        try {
            DictionaryResponse dictionary = dicInfoMap.get(key);
            if (dictionary != null) {
                return dictionary;
            }
            retryBuildLocalCache(dicInfoMap);
            DictionaryResponse dicByItemKeyWithIfc = getDicByItemKeyWithIfc(key);
            if(null != dicByItemKeyWithIfc){
                return dicByItemKeyWithIfc;
            }
            logger.warn("======Not Found Dic key:" + key);
            throw new BusinessException("未发现所需要的字典数据:"+key);
        }finally {
            r.unlock();
        }

    }

    /**
     * 通过itemKey查询字典ID
     * @param key
     * @return
     */
    public static int getDicIdByItemKey(String key) {
        r.lock();
        try {
            DictionaryResponse dictionary = dicInfoMap.get(key);
            if (dictionary != null) {
                return Detect.asPrimitiveInt(dictionary.getId());
            }
            retryBuildLocalCache(dicInfoMap);
            DictionaryResponse dicByItemKeyWithIfc = getDicByItemKeyWithIfc(key);
            if(null != dicByItemKeyWithIfc){
                return dicByItemKeyWithIfc.getId();
            }
            logger.warn("======Not Found Dic key:" + key);
            throw new BusinessException("未发现所需要的字典数据:"+key);
        }finally {
            r.unlock();
        }
    }

    /**
     * 通过itemKey查询字典中文名称
     * @param key
     * @return
     */
    public static String getDicNameByItemKey(String key) {
        r.lock();
        try {
            DictionaryResponse dictionary = dicInfoMap.get(key);
            if (dictionary != null) {
                return Detect.asString(dictionary.getItemNamecn());
            }
            retryBuildLocalCache(dicInfoMap);
            DictionaryResponse dicByItemKeyWithIfc = getDicByItemKeyWithIfc(key);
            if(null != dicByItemKeyWithIfc){
                return dicByItemKeyWithIfc.getItemNamecn();
            }
            logger.warn("======Not Found Dic key:" + key);
            throw new BusinessException("未发现所需要的字典数据:"+key);
        }finally {
            r.unlock();
        }
    }

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

    /**
     * 通过ID查询字典itemKey
     * @param id
     * @return
     */
    public static String getDicItemKeyById(Integer id) {
        r.lock();
        try {
            DictionaryResponse dictionary = dicInfoIsMap.get(id);
            if (dictionary != null) {
                return Detect.asString(dictionary.getItemKey());
            } else {
                retryBuildLocalCache(dicInfoIsMap);
                DictionaryResponse 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
     * @return
     */
    public static Integer getDicParentIdById(Integer id) {
        r.lock();
        try {
            DictionaryResponse dictionary = dicInfoIsMap.get(id);
            if (dictionary != null) {
                return dictionary.getParentId();
            } else {
                retryBuildLocalCache(dicInfoIsMap);
                DictionaryResponse dicByItemKeyWithIfc = getDicByIdWithIfc(id);
                if(null != dicByItemKeyWithIfc){
                    return dicByItemKeyWithIfc.getParentId();
                }
                logger.warn("======Not Found Dic id:" + id);
                return null;
            }
        }finally {
            r.unlock();
        }
    }

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

    /*------------------------------------------partner by id-------------------------------------------*/
    /**
     * 通过ID查询合作方
     * @param id
     * @return
     */
    public static PartnerResponse getPartnerById(Integer id) {
        r.lock();
        try {
            PartnerResponse cmsPartner = parInfoIsMap.get(id);
            if (cmsPartner != null) {
                return cmsPartner;
            } else {
                PartnerResponse partnerByIdWithIfc = getPartnerByIdWithIfc(id);
                if(null != partnerByIdWithIfc){
                    return partnerByIdWithIfc;
                }
                logger.warn("======Not Found Partner id:" + id);
                return null;
            }
        }finally {
            r.unlock();
        }
    }

    /**
     * 通过ID查询合作方名称
     * @param id
     * @return
     */
    public static String getPartnerNameById(Integer id) {
        r.lock();
        try {
            PartnerResponse cmsPartner = parInfoIsMap.get(id);
            if (cmsPartner != null) {
                return Detect.asString(cmsPartner.getName());
            } else {
                PartnerResponse partnerByIdWithIfc = getPartnerByIdWithIfc(id);
                if(null != partnerByIdWithIfc){
                    return partnerByIdWithIfc.getName();
                }
                logger.warn("======Not Found Partner id:" + id);
                return null;
            }
        }finally {
            r.unlock();
        }
    }


     /*------------------------------------------liveAisle by id-------------------------------------------*/
    /**
     * 通过ID查询直播频道
     * @param id
     * @return
     */
    public static LiveAisleResponse getLiveAisleById(Integer id) {
        r.lock();
        try {
            LiveAisleResponse liveAisleResponse = liveInfoIsMap.get(id);
            if (liveAisleResponse != null) {
                return liveAisleResponse;
            } else {
                LiveAisleResponse liveAisleByIdWithIfc = getLiveAisleByIdWithIfc(id);
                if(null != liveAisleByIdWithIfc){
                    return liveAisleByIdWithIfc;
                }
                logger.warn("======Not Found LiveAisle id:" + id);
                return null;
            }
        }finally {
            r.unlock();
        }
    }

    /**
     * 通过ID查询直播频道名称
     * @param id
     * @return
     */
    public static String getLiveAisleChannelById(Integer id) {
        r.lock();
        try {
            LiveAisleResponse liveAisleResponse = liveInfoIsMap.get(id);
            if (liveAisleResponse != null) {
                return Detect.asString(liveAisleResponse.getChannel());
            } else {
                PartnerResponse partnerByIdWithIfc = getPartnerByIdWithIfc(id);
                if(null != partnerByIdWithIfc){
                    return partnerByIdWithIfc.getName();
                }
                logger.warn("======Not Found LiveAisle id:" + id);
                return null;
            }
        }finally {
            r.unlock();
        }
    }


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

    /**
     * 初始化内存数据
     * 字典/合作方
     */
    public static void buildLocalCache(List<DictionaryResponse> dataDic,List<PartnerResponse> partnerDic,List<LiveAisleResponse> liveAisles){
        w.lock();
        try {
            //初始化数据字典
            logger.warn("-------------------init dictionary start...---------------------");
            for (DictionaryResponse dictionaryResponse : dataDic) {
                dicInfoMap.put(Detect.trim(dictionaryResponse.getItemKey()), dictionaryResponse);
                dicInfoIsMap.put(dictionaryResponse.getId(), dictionaryResponse);
            }
            logger.warn("-------------------init dictionary complete---------------------");
            //初始化合作方
            logger.warn("-------------------init partnerMap start...---------------------");
            for (PartnerResponse partnerResponse : partnerDic) {
                parInfoIsMap.put(partnerResponse.getId(), partnerResponse);
            }
            logger.warn("-------------------init partnerMap complete---------------------");
            //初始化直播频道
            logger.warn("-------------------init liveAisleMap start...---------------------");
            for (LiveAisleResponse liveAisleResponse : liveAisles) {
                liveInfoIsMap.put(liveAisleResponse.getId(), liveAisleResponse);

            }
            logger.warn("-------------------init liveAisleMap complete---------------------");
        } catch (Exception e){
            e.printStackTrace();
            throw new BusinessException("初始化字典或合作方失败!");
        } finally{
            w.unlock();
        }
    }

    /**
     * 重试机制
     * 若多次发现本地缓存为空 则重新加载本地数据
     */
    private static void retryBuildLocalCache(Map<?,DictionaryResponse> 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 = JsonUtil.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 = JsonUtil.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(List<DictionaryResponse> dictionaryResponses){
        ZkClientUtils zkClientUtils = new ZkClientUtils();
        int success = 1;
        w.lock();
        try {
            String data = JsonUtil.list2json(dictionaryResponses);
            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"/>

猜你喜欢

转载自blog.csdn.net/u013985664/article/details/79570558