使用Spring ApplicationListener实现项目启动初始化数据缓存

来源:互联网 发布:华腾软件 编辑:程序博客网 时间:2024/06/10 03:11

使用Spring ApplicationListener实现项目启动初始化数据缓存

  • 版权声明:本文为博主原创文章,转载请写明出处。

使用场景

在一些业务场景中,当容器初始化完成之后,需要处理一些操作,比如一些数据的加载、初始化缓存、特定任务的注册等等。这个时候我们就可以使用Spring提供的ApplicationListener来进行操作。

用法

本文以在Spring boot下的使用为例来进行说明。首先,需要实现ApplicationListener接口并实现onApplicationEvent方法。把需要处理的操作放在onApplicationEvent中进行处理:

package com.reminance.xc.cache;import org.springframework.context.ApplicationListener;import org.springframework.context.event.ContextRefreshedEvent;import org.springframework.stereotype.Component;/**  * @author Reminance * @date 2017年8月28日 下午6:01:24  */@Componentpublic class CacheInitManager implements ApplicationListener<ContextRefreshedEvent> {    /* (non-Javadoc)     * @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)     */    @Override    public void onApplicationEvent(ContextRefreshedEvent event) {        //root application context 没有parent,他就是老大.        if(event.getApplicationContext().getParent() == null){            BusinessLogicCacheManager businessLogicCacheManager = (CameraStatusCacheManager) event.getApplicationContext().getBean(                    "businessLogicCacheManager");            if (businessLogicCacheManager != null) {                //此处可以做数据库初始化数据的相关操作:比如定义CacheManager,使用Dao读取数据库数据放入缓存。                businessLogicCacheManager.init(event.getApplicationContext());               }        }    }}

二次调用问题

在使用传统的application.xml和project-servlet.xml配置中会出现二次调用的问题。主要原因是初始化root容器之后,会初始化project-servlet.xml对应的子容器。我们需要的是只执行一遍即可。那么上面打印父容器的代码用来进行判断排除子容器即可。在业务处理之前添加如下判断:

if(contextRefreshedEvent.getApplicationContext().getParent() != null){            return;}

这样其他容器的初始化就会直接返回,而父容器(Parent为null的容器)启动时将会执行相应的业务操作。

关联知识

在spring中InitializingBean接口也提供了类似的功能,只不过它进行操作的时机是在所有bean都被实例化之后才进行调用。根据不同的业务场景和需求,可选择不同的方案来实现。

下面补充缓存类代码

此处定义接口:

package com.reminance.xc.cache;/**  * 缓存元素接口定义 * @author Reminance * @date 2017年8月30日 上午11:05:59  */public interface ICacheManager<T> {    /**     * 缓存元素     * @author Reminance     * @date 2017年8月30日 上午11:10:28     * @param key     * @param obj     */    void store(String key, T obj);    /**     * 删除元素     * @author Reminance     * @date 2017年8月30日 上午11:10:54     * @param key     */    void remove(String key);    /**     * 修改元素     * @author Reminance     * @date 2017年8月30日 上午11:11:21     * @param key     * @param obj     */    void modify(String key, T obj);    /**     * 缓存元素, 设置超时时间     * @author Reminance      * @date 2017年8月30日 上午11:12:26     * @param key     * @param obj     * @param exp     */    void store(String key, T obj, Long exp);    /**     * 修改元素, 设置超时时间     * @author Reminance     * @date 2017年8月30日 上午11:13:03     * @param key     * @param obj     * @param exp     */    void modify(String key, T obj, Long exp);    /**     * 判断key是否存在     * @author Reminance     * @date 2017年8月30日 上午11:18:44     * @param key     * @return     */    boolean exist(String key);    /**     * 获取值     * @author Reminance     * @date 2017年8月30日 上午11:19:33     * @param key     * @return     */    T get(String key);}

此处定义接口实现:

package com.Reminance.xc.cache;import java.util.List;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.ApplicationContext;import org.springframework.stereotype.Component;import com.Reminance.cms.cache.manager.DataLoadException;import com.Reminance.cms.cache.manager.DataManager;import com.Reminance.xc.bo.ElementInfo;import com.Reminance.xc.constant.ElementType;import com.Reminance.xc.constant.ElementConstant;import com.Reminance.xc.core.util.CollectionUtils;import com.Reminance.xc.service.BusinessLogicService;/**  * @author Reminance * @date 2017年8月28日 下午5:10:30  */@Component("businessLogicCacheManager")public class BusinessLogicCacheManagerimpl implements ICacheManager<Integer> {    private static final Logger log = LoggerFactory.getLogger(BusinessLogicCacheManagerimpl .class);    public static final String NODE_PRE = "businessLogic";    public static final String NODE_STATUS_PRE = "businessLogic_status_";    @Autowired    private ICacheManager<String> elementSourceAndIdCacheManager;    @Autowired    private DataManager dataManager;    public void init(ApplicationContext applicationContext) {        try {            BusinessLogicService businessLogicService = (BusinessLogicService ) applicationContext.getBean("businessLogicService ");            if (businessLogicService != null) {                List<ElementInfo> list = businessLogicService .getByElementType(ElementType.ELEMENT.getType());                if (CollectionUtils.isNotEmpty(list)) {                    for (final ElementInfo info : list) {                        store(info.getSourceId(), info.getStatus() == null ? -1 : info.getStatus());                        elementSourceAndIdCacheManager.store(ElementConstant.ELEMENT_NODE_PRE_CODE + "pk_" + info.getId().toString(), info.getSourceId());                    }                }            }        } catch (Exception e) {            log.error("init ElementInfo cache error", e);        }    }    @Override    public void store(String key, Integer obj) {        try {            dataManager.setObject(NODE_STATUS_PRE + key, obj);        } catch (DataLoadException e) {            log.error("store ElementInfo status error", e);        }    }    @Override    public void remove(String key) {        try {            dataManager.remove(NODE_STATUS_PRE + key);        } catch (DataLoadException e) {            log.error("remove ElementInfo status error", e);        }    }    @Override    public void modify(String key, Integer obj) {        try {            dataManager.setObject(NODE_STATUS_PRE + key, obj);        } catch (DataLoadException e) {            log.error("modify ElementInfo status error", e);        }    }    @Override    public void store(String key, Integer obj, Long exp) {        try {            dataManager.setObject(NODE_STATUS_PRE + key, obj, exp);        } catch (DataLoadException e) {            log.error("store ElementInfo status by expire time error", e);        }    }    @Override    public void modify(String key, Integer obj, Long exp) {        try {            dataManager.setObject(NODE_STATUS_PRE + key, obj, exp);        } catch (DataLoadException e) {            log.error("modify ElementInfo status by expire time error", e);        }    }    @Override    public boolean exist(String key) {        Integer status = get(key);        return status == null ? false : true;    }    @Override    public Integer get(String key) {        try {            Integer obj = (Integer) dataManager.getObject(NODE_STATUS_PRE + key);            return obj;        } catch (DataLoadException e) {            log.error("get ElementInfo status  error", e);        }        return null;    }}

记录点滴 共同进步 
文中有错误或不同意见欢迎私信指正


阅读全文
0 0