页面缓存:通过ThymeleafViewResolver实现页面缓存,一些高并发的页面可以将整个页面存到缓存中这样就可以不用每次都从数据库查询,解决高并发问题。
Cache
ThymeleafViewResolver
各类前端模板引擎的页面展示,发现它们的共性时,都实现了ViewResolver接口,并将实现类注入到Spring容器当中。 以Thymeleaf为例,在它的自动配置类中实现如下:
@Bean
@ConditionalOnMissingBean(name = "thymeleafViewResolver")
ThymeleafViewResolver thymeleafViewResolver(ThymeleafProperties properties,
SpringTemplateEngine templateEngine) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
// ...
return resolver;
}
很明显它定义了ThymeleafViewResolver,而该类最终也是实现了ViewResolver接口。 本篇文章就带大家了解一下ViewResolver的功能和在SpringBoot中如何自定义。
ViewResolver的作用
ViewResolver的作用就是通过解析ModelAndView,将ModelAndView中的逻辑视图名映射为View对象,并将ModelAndView中的Model取出。
View在获取到ViewResolver传递的View和Model时,对Model进行渲染,通过View对象找到要展示给用户的物理视图,将渲染后的视图展示给用户。直白的说将就是将数据通过request存储起来,存放在展示给用户的页面中,并将页面呈现给用户。
实例化的ViewResolver存储在DispatcherServlet的List
该段参考于
SpringBoot2.x系列教程(三十五)SpringMVC之ViewResolver及扩展
SpringBoot实战
案例:GoodsController商品页面的并发访问
页面缓存之前GoodsController
@Controller
@RequestMapping("/goods")
public class GoodsController {
@Autowired
private ISeckillGoodsService iSeckillGoodsService;
@Autowired
private RedisTemplate<String,Object> redisTemplate;
@Autowired
private ThymeleafViewResolver thymeleafViewResolver;
@RequestMapping("/toList")
public String toList(User user, Model model, HttpServletRequest request){
//1判断用户是否登录
if (user == null)
return "login";
model.addAttribute("user",user);
//2查询所有秒杀商品信息
List<SeckillGoodsVo> list = iSeckillGoodsService.tolist();
model.addAttribute("goodsVoList",list);
return "goodsList";
}
}
使用Jmeter压测结果 吞吐量在1400左右
页面缓存之后GoodsController
@Controller
@RequestMapping("/goods")
public class GoodsController {
@Autowired
private ISeckillGoodsService iSeckillGoodsService;
@Autowired
private RedisTemplate<String,Object> redisTemplate;
@Autowired
private ThymeleafViewResolver thymeleafViewResolver;
@RequestMapping("/toList")
@ResponseBody
public String toList2(User user, Model model, HttpServletRequest request, HttpServletResponse response){
//1.判断用户是否登录
if (user == null)
throw new GlobalException(RespBeanEnum.LOGIN_NOT_LOGIN);
//2.从redis中取出页面缓存
String html = (String) redisTemplate.opsForValue().get("goodsList");
if (!StringUtils.isEmpty(html)) {
return html;
}
model.addAttribute("user",user);
//2查询所有秒杀商品信息
List<SeckillGoodsVo> list = iSeckillGoodsService.tolist();
model.addAttribute("goodsVoList",list);
//ViewResolver把数据糅合到一起
//ThymeleafViewResolver thymeleafViewResolver = new ThymeleafViewResolver();
//需要一个web的上下文
WebContext webContext = new WebContext(request,response,request.getServletContext(),request.getLocale(),model.asMap());
//需要WebContext参数
html = thymeleafViewResolver.getTemplateEngine().process("goodsList",webContext);
//3.保存到redis
redisTemplate.opsForValue().set("goodsList",html,60, TimeUnit.SECONDS);
return html;
}
}
使用Jmeter压测结果 吞吐量在3000-5000
明显能够看出页面缓存之后,并发效率的提高。