优化--字典值/轮播图缓存优化以及页面静态化

相关文章:
SpringAOP配置切面报错
nginx代理静态图片
spring和redis的整合

一、字典值的优化

在项目中,枚举字典表做了一些优化,在程序启动的时候将数据一次性加载到内存,当字典表变化时(增删改)把内存数据重新加载一次,这个功能是通过AOP结合自定义注解完成的。

1.初始化代码

@Component
public class DictParamUtil {

    @Autowired
    private IDictTypeDao typeDao;// 注入字典类型DAo接口

    private Log logger = LogFactory.getLog(DictParamUtil.class);

    private Map<Integer, Map<Integer, String>> dicMap = new HashMap<>();


    /**
     * 初始化下拉框列表
     */
    @PostConstruct
    public void initDicMap(){
        // 清空下拉框Map
        dicMap.clear();
        // 把所有字典类型取出来
        List<DictType> typeList = typeDao.queryAllObj(new DictTypeCond());

        Map<Integer,String> map = null;
        DictCond cond = new DictCond();
        List<Dict> dictList = null;

        for (DictType dictType : typeList) {

            map = new HashMap<Integer, String>();
            // 根据字典类型查询所有的字典值
            cond.setType_code_c(dictType.getType_code());// 条件:类型编码
            dictList = dictService.queryAllObj(cond);

            for (Dict dict : dictList) {
                map.put(dict.getData_key(), dict.getData_value());
            }

            dicMap.put(dictType.getType_code(), map);
        }

        logger.info("-------------------------字典值下拉框初始化完成-------------------------");
    }
}   

每次对字典类型和字典值修改之后重新初始化

2.定义切面

@Component
@Aspect
public class DicAspect {

    public Log logger = LogFactory.getLog(getClass());

    @Autowired
    private DictParamUtil util;

    @After("within(com.cms.sys.dict*.service.impl..*) && @annotation(dic)")
    public void execute(JoinPoint point , DicAnnotation dic){
        util.initDicMap();
        logger.info("------------------" + point.getSignature() + "初始化字典值------------------");
    }
}

3.自定义注解

@Target(ElementType.METHOD) // 用在方法上
@Retention(RetentionPolicy.RUNTIME) // 运行时有效
public @interface DicAnnotation {

}

二、对轮播图的优化

轮播图的数据较多,保存到redis中。当请求首页的时候,先去redis中查找缓存是否存在,不存在的话通过HttpClient请求数据接口api得到轮播图数据。这个数据是json格式的,再转成list集合。当对轮播图进行修改操作时会清空redis。也是采用AOP+自定义注解的方式完成的。

1.代码实现

/**
 * @功能描述 首页相关业务逻辑实现
 * @author zhaoj
 */
@Service
public class HomeServiceImpl implements IHomeService {

    @Autowired
    private HttpUtil httpUtil;// 注入发送请求的工具类
    @Autowired
    private RedisTemplate<String,String> template;

    private Log logger = LogFactory.getLog(getClass());

//  @Override
//  public List<Banner> queryBanners() {
//      
//      Jedis jedis = new Jedis("ip",6379);
//      // 得到PC端的轮播图,1-PC端,2-M站
//      String str = jedis.get(ApplicationConstant.BANNER_PC);
//      
//      // 如果缓存中没有轮播图相关信息,调用接口查询
//      if( str == null){
//          str = httpUtil.getTextOfGet("banner/list?type=1");
//          logger.info("-------------------------进入查询------------------------------");
//          jedis.set(ApplicationConstant.BANNER_PC, str);
//          jedis.close();
//      }
//  
//      Banner[] banners = GenerateJsonUtil.generateObj(str, Banner[].class);
//      // 将数组转成集合list
//      List<Banner> list = Arrays.asList(banners);
//      
//      return list;
//  }

    @Override
    public List<Banner> queryBanners() {

        ValueOperations<String,String> opsForValue = template.opsForValue();
        // 得到PC端的轮播图,1-PC端,2-M站
        String str = (String) opsForValue.get(ApplicationConstant.BANNER_PC);

        // 如果缓存中没有轮播图相关信息,调用接口查询
        if( str == null ){
            str = httpUtil.getTextOfGet("banner/list?type=1");
            logger.info("-------------------------进入查询------------------------------");
            logger.info("-------------------------"+str+"------------------------------");
            opsForValue.set(ApplicationConstant.BANNER_PC, str);
        }

        Banner[] banners = GenerateJsonUtil.generateObj(str, Banner[].class);
        // 将数组转成集合list
        List<Banner> list = Arrays.asList(banners);

        return list;
    }

}

2.切面类

/**
 * 轮播图切面类
 * @author zhaoj
 */
@Component
@Aspect
public class BannerAspect {

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    private Log logger = LogFactory.getLog(getClass());

    @After("within(com.cms.banner.service..*) && @annotation(ann)")
    public void clearBannerRedis(JoinPoint point ,BannerAnnotation ann){

        ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
        // 清除redis
        opsForValue.set(Constant.BANNER_PC, null);

        logger.info("执行了" + point.getSignature() + "清空redis !!!");
    }

}

3.请求工具类

/**
 * 连接api的工具类
 * @author zhaoj
 */
@Component
public class HttpUtil {

    @Autowired
    private Config config;

    private Log logger = LogFactory.getLog(getClass());

    /**
     * get请求返回响应内容
     * @param uri
     * @return
     */
    public String getTextOfGet(String uri){

        // 创建HttpClient
        HttpClient client = HttpClients.createDefault();
        // 创建get请求
        HttpGet get = new HttpGet(config.getApi_url() + uri);

        String text = "";

        try {
            // 客户端连接请求
            HttpResponse response = client.execute(get);
            // 得到响应的实体
            HttpEntity entity = response.getEntity();
            // 得到实体内容
            text = EntityUtils.toString(entity);

        } catch (ClientProtocolException e) {
            logger.info("get请求抛出ClientProtocolException异常!");
            e.printStackTrace();
        } catch (IOException e) {
            logger.info("get请求抛出IOException异常!");
            e.printStackTrace();
        } finally {
            // 必须释放资源
            get.releaseConnection();
        }
        return text;
    }

    /**
     * 得到post请求的响应结果
     * @param uri 请求路径
     * @param map 请求体携带的参数
     * @return
     */
    public String getTextOfPost(String uri, Map<String,String> map){

        // 创建HttpClient
        HttpClient client = HttpClients.createDefault();
        // 创建post请求
        HttpPost post = new HttpPost(config.getApi_url() + uri);
        // 创建名值对list
        List<NameValuePair> list = new ArrayList<NameValuePair>();
        BasicNameValuePair basic = null;
        String text = "";

        // 遍历map,向list中添加数据
        for (Map.Entry<String, String> entry : map.entrySet()) {
            // BasicNameValuePair implements NameValuePair
            basic = new BasicNameValuePair(entry.getKey(), entry.getValue());
            list.add(basic);
        }
        try {
            // 把参数编码到表单实体中
            UrlEncodedFormEntity entityPost = new UrlEncodedFormEntity(list,"UTF-8");
            // 把表单实体放到请求中
            post.setEntity(entityPost);
            // 用客户端去执行post请求
            HttpResponse response = client.execute(post);
            HttpEntity entity = response.getEntity();// 从响应中取出响应实体
            text = EntityUtils.toString(entity);
        } catch (IOException e) {
            logger.info("post请求抛出IOException异常!");
            e.printStackTrace();
        } finally {
            post.releaseConnection();
        }
        return text;
    }
}   

4.json工具类

/**
 * 有关操作json的工具类
 * @author zhaoj
 */
public class GenerateJsonUtil {

    private static Log logger = LogFactory.getLog(GenerateJsonUtil.class);

    /**
     * 将json格式的字符串转成对象
     * @param json 待转的字符串
     * @param clazz 对象的class
     * @return
     */
    public static <T> T generateObj(String json, Class<T> clazz) {

        T obj = null;
        ObjectMapper mapper = new ObjectMapper();
        try {
            obj  = mapper.readValue(json, clazz);
        } catch (JsonParseException e) {
            logger.info("字符串转对象抛出JsonParseException异常!!!");
            e.printStackTrace();
        } catch (JsonMappingException e) {
            logger.info("字符串转对象抛出JsonMappingException异常!!!");
            e.printStackTrace();
        } catch (IOException e) {
            logger.info("字符串转对象抛出IOException异常!!!");
            e.printStackTrace();
        }

        return obj;
    }

    /**
     * 将对象转换成json格式的字符串
     * @param obj 对象
     * @return
     */
    public static String generateJson(Object obj){

        String json = "";
        ObjectMapper mapper = new ObjectMapper();
        try {
            json = mapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            logger.info("对象转字符串抛出JsonProcessingException异常!!!");
            e.printStackTrace();
        }
        return json;

    }
}

三、首页静态化

通过httpClient请求动态首页,获取页面内容,把它写到nginx代理过的文件夹下。

1.代码实现

@Serivce
public class HomeServiceImpl implements HomeService{

    @Autowired
    private HttpUtil util;

    public Log logger = LogFactory.getLog(getClass());

    @Override
    public void runStatic() {
        // 得到首页的文本信息
        String text = util.getTextOfGet("home/index.do");
        // 替换字符
        text = text.replaceAll("/resources/", "http://img.power.static/");
        logger.info(text);

        // 保存到文件中
        // 保存的地址
        String dest = "D:/img/home/index.html";
        File file = new File(dest);
        File parentFile = file.getParentFile();
        if(!parentFile.exists()){
            parentFile.mkdirs();
        }

        // 装饰者模式,只关闭高级流
        BufferedWriter writer = null;
        try {

            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
            writer.write(text);

        } catch (FileNotFoundException e) {
            logger.info("--------------------复制文件抛出FileNotFoundException--------------------");
            e.printStackTrace();
        } catch (IOException e) {
            logger.info("--------------------复制文件抛出IOException--------------------");
            e.printStackTrace();
        } finally {
            try {
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

2.nginx配置

在nginx代理的文件夹下
新建一个文件夹static,存放首页需要的css,js,icon
新建一个文件夹home,存放首页index.html

server {
listen 80;
server_name img.power.home;
#只过滤以.html 结尾的请求
location ~ .*\.(html)$ {
root D:/img/home;
index index.html;
}
#其它请求
location / {
proxy_pass http://localhost;
proxy_connect_timeout 500ms;
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值