• Java缓存类的实际应用场景


    不要着迷于技术,应把注意力放到问题上。

      一个普通的后台管理系统,一定会有参数配置。参数配置数据表和其他的数据表是不同的,它的操作基本都是查的操作。参数配置的这些数据信息是贯穿在整个项目中,那么把他们放到哪里可以方便类或者jsp的调用?

    spring的配置文件有支持缓存类,它的配置如下:

     <!-- 启用用户的缓存功能 -->  
        <bean id="userCache" class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache">  
            <property name="cache" ref="userEhCache" />  
        </bean>  
        <bean id="userEhCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">  
            <property name="cacheName" value="userCache" />  
            <property name="cacheManager" ref="ehcacheManager" />  
        </bean>
        <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-ref="ehcacheManager"/>
        <bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:config-location="classpath:config/ehcache.xml"/>

      

    然后在我们自己的缓存类中加入相应的注解即可:

    package cn.wangze.service;
    
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cache.annotation.CacheEvict;
    import org.springframework.cache.annotation.Cacheable;
    import org.springframework.stereotype.Service;
    
    import cn.wangze.domain.SysMenu;
    import cn.wangze.domain.SysParam;
    import cn.wangze.utils.AuthUtils;
    
    @Service
    public class SysCacheService{
        
        //具体需要缓存的数据视自己业务而定
        /**
         * 项目中菜单的数据很少变动,所以我们把菜单数据也放到缓存里面
         * */
        @Autowired
        private SysMenuService<SysMenu> sysMenuService;
        
        /**
         * 注入系统参数的service
         * */
        @Autowired
        private SysParamService<SysParam> SysParamService;
            
        /**
         * 创建Map对象保存系统参数的数据,方便调用
         */
        private Map<String,String> sysParamMap;
        
        /**
         * 通过调用这个方法可以取到缓存的菜单数据
         */
        @Cacheable(value="sysCache",key="methodName")
        public List<SysMenu> queryMenuList(){
            List <SysMenu> list = sysMenuService.queryList();
            if(list == null || list.size() == 0) return null;
            AuthUtils.clear();
            for(int i=0;i<list.size();i++){
                SysMenu m = list.get(i);
                AuthUtils.addAuth(m.getId(), m.getUrl());
            }
            return list;
        }
        
        /**
         * 清除缓存中的某些数据,如果参数type为querySysParamList则全部清空
         * */
        @CacheEvict(value="sysCache",key="#p0")
        public void removeCatch(String type){
            if(type.equals("querySysParamList")){
                this.sysParamMap = null;
            }
        }
        
        /**
         * 清除缓存中的全部数据
         * */
        @CacheEvict(value="sysCache",allEntries=true)
        public void removeAll(){
            this.sysParamMap = null;
        }
        
        /**
         * 查看缓存中全部数据
         * */
        @Cacheable(value="sysCache",key="methodName")
        public List<SysParam> querySysParamList(){
            return SysParamService.queryList(null);
        }
        
        /**
         * 输入保存的key值,拿到对应的value。这个方法会经常用到。
         * */
        public String getSysParam(String key){
            if(this.sysParamMap == null){
                this.sysParamMap = new HashMap<String,String>();
                for(SysParam param: querySysParamList()){
                    sysParamMap.put(param.getKey(), param.getValue());
                }
            }
            return this.sysParamMap.get(key);
        }
    
    }

      我们的缓存类SysCacheService就算写好了。可以看到第一次我们调用queryMenuList或者getSysParam方法时,如果map为空会从数据库中拿,如果map内部有数据存在,会直接从map拿数据。数据是以键值对的形式保存的。当我们想调用里面的数据时,只需要在操作类中注入SysCacheService,然后调用对应的方法。

     

    举个例子,我的数据结构是这样的:

    这是我的项目中的参数配置表,因为以前是oracle数据库,后来我把数据导入到mysql数据库里面时发现字段命名为"key"和"value"的话,查询sql语句会报错,所以换成了"keyaa"和"valueaa"。

    MyController类想用一下系统配置的sms_url的值:

    public String getSmsUrl(){
        String sms_url =sysCacheService.getParam("sms_url");
        return sms_url ;
    }

    在MyController类中注入SysCacheService对象sysCacheService,并调用它的方法,传入参数"sms_url"就ok了。

     

    后来,我想了想有没有更好的办法,把缓存放到一个类似工具类的静态类里面呢,这样就不用每次用到缓存数据都得注入一个SysCacheService了。方法如下:

    1.在配置文件中添加一个servlet上下文的监听器,当servlet加载时,把SysCacheService放到静态类里面

    2.在静态类中声明方法,代理SysCacheService的方法调用

      xml配置文件增加一个listener:

    <!-- 监听器,用于将缓存SysCacheService类封装成静态类 -->
        <listener>
            <listener-class>
                cn.wangze.listener.MyContextListener
            </listener-class>
        </listener>
    MyContextListener代码如下:
    package cn.wangze.listener;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    
    import org.springframework.web.context.support.WebApplicationContextUtils;
    
    import cn.wangze.Constants;
    import cn.wangze.service.SysCacheService;
    
    public class MyContextListener implements ServletContextListener{
    
        @Override
        public void contextDestroyed(ServletContextEvent arg0) {
        }
    
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            
            ServletContext sc =  sce.getServletContext();
            SysCacheService sysCacheService = WebApplicationContextUtils.getWebApplicationContext(sc).getBean(SysCacheService.class);
            Constants.setSysCacheService(sysCacheService);
        }
    }

    静态类的代码如下:

    package cn.wangze;
    
    import cn.wangze.service.SysCacheService;
    
    
    public class Constants {
        private static SysCacheService sysCacheService;
        public static SysCacheService getSysCacheService(){
            return sysCacheService;
        }
        
        public static void setSysCacheService(SysCacheService sysCacheService){
            Constants.sysCacheService = sysCacheService;
        }
        
        public static String getParam(String key){
            return sysCacheService.getSysParam(key);
        }
    }

      这样,我们每次用到缓存数据时候,只需要引入Constants静态类,并直接用类名+方法名调用数据就行了。 

  • 相关阅读:
    OpenGL ES 三种类型 uniform attribute varying
    Android显示YUV图像
    Android设置全屏
    Android 显示YUV编码格式
    关于Nexus 7的Usb host开发问题
    Android关闭系统锁屏
    java基础之Java变量命名规范
    java环境变量详解---找不到或无法加载主类
    PowerDesigner使用教程 —— 概念数据模型 (转)
    SQL Server高级内容之表表达式和复习
  • 原文地址:https://www.cnblogs.com/blue-wz/p/7512227.html
Copyright © 2020-2023  润新知