我是靠谱客的博主 敏感茉莉,最近开发中收集的这篇文章主要介绍使用 @CacheResult 注解 使用Hystrix 请求缓存,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1. 消费端 Controller 代码

package com.example.server1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.model.User;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandProperties;
import scala.annotation.meta.param;
@RestController
public class UserController {
@Autowired
UserService userService;
//RestTemplate restTemplate;
/*
* 由于我们这里使用的是 http://localhost:9000/users?id=4&name=liubei&xingBie 的方式访问,
* 所以需要使用 @RequestParam 注解把请求参数的值绑定到方法的参数上。
* */
/*@RequestMapping(value="/users",method=RequestMethod.GET)
public User UserConsumber(@RequestParam(value="id") Long id,@RequestParam(value="name")
String name,@RequestParam(value="xingBie") String xingBie) {
//return restTemplate.getForEntity("http://hello-service/hello", String.class).getBody();
System.out.println("UserController 方法");
System.out.println("id:" + id + "
name:"+name + "
xingBie:"+xingBie );
return userService.getUserById(id,name,xingBie);
}*/
@RequestMapping(value="/users",method=RequestMethod.GET)
public User UserConsumber(@RequestParam(value="id") Long id) {
//return restTemplate.getForEntity("http://hello-service/hello", String.class).getBody();
System.out.println("UserController 方法");
System.out.println("id:" + id );
return userService.getUserById(id);
}
}

2. 消费端 service 代码

package com.example.server1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.model.User;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheKey;
import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheResult;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;
@Service
public class UserService {
@Autowired
private RestTemplate restTemplate;
private Long id;
private String name = "caocao";
private String
xingBie = "男";
private User user;
@CacheResult(cacheKeyMethod = "getCacheKey")
@HystrixCommand
public User getUserById(Long id) {
System.out.println("getUserById 方法");
user = restTemplate.getForObject("http://hello-service/users/{id}/{name}/{xingBie}", User.class,id,name,xingBie);
System.out.println("getUserById 方法
user:"+ user.getId() +"
" + user.getName() +"
" + user.getXingBie());
return user;
}
/*@CacheResult(cacheKeyMethod = "getCacheKey")
@HystrixCommand(commandKey = "commandKey1")
public Long getUserById(Long id) {
System.out.println("getUserById 方法");
this.id=id;
// user = restTemplate.getForObject("http://hello-service/users/{id}/{name}/{xingBie}", User.class,id,name,xingBie);
//System.out.println("getUserById 方法
user:"+ user.getId() +"
" + user.getName() +"
" + user.getXingBie());
return this.id;
}*/
// getCacheKey 方法的参数要与 getUserById 方法保持一致否则会报错
//public String getCacheKey(Long id,String name,String xingBie) {
public String getCacheKey(Long id) {
//HystrixRequestContext.initializeContext(); // 缓存上线文初始化代码放在这个方法中,会导致每次调用这个方法缓存都会被清空(初始化)
System.out.println("执行缓存方法:" + id );
//System.out.println("查看缓存数据:"
+ String.valueOf(id));
//return String.valueOf(this.id) + String.valueOf(this.name) + String.valueOf(this.xingBie);
return String.valueOf(id);
}
}

 

3. 消费端 过滤器代码。注意过滤器类和过滤器注册配置类都要与工程中的 springboot 主类放在同一个包中。

package com.support;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;
@Component
public class HystrixInterceptor implements HandlerInterceptor {
Integer i = 0;
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,Object handler) throws Exception {
System.out.println("执行控制器之前执行拦截器");
if (i==0) {
HystrixRequestContext.initializeContext();
//return true;
i++;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("执行控制器之后执行拦截器");
//HystrixRequestContext.initializeContext();
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,Object handler ,
Exception ex) throws Exception {
System.out.println("前端控制器之后执行拦截器");
}
}

4. 过滤器注册配置类

package com.example.server1;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WebComponent2Config {
@Bean
public FilterRegistrationBean someFilterRegistration1() {
//新建过滤器注册类
FilterRegistrationBean registration = new FilterRegistrationBean();
// 添加我们写好的过滤器
registration.setFilter( new HystrixRequestContextServletFilter());
// 设置过滤器的URL模式
registration.addUrlPatterns("/*");
return registration;
}
}

5. 通过浏览器访问消费端

6. 消费端和服务端控制台输出的日志

6.1 消费端控制台日志

6.2 服务端控制台日志

通过控制台的输出我们看到,通过浏览器访问两次,两次都调用了 SERVER 端,缓存并没效果。
通过测试分析,每次请求通过过滤器时都会重新初始化 Hystrix  缓存上下文。如果不让初始化就会报错。
如何才能让缓存起效果,消费端在第一次被访问的后续访问不再调服务端,直接通过缓存返回数据给浏览器。

 

7. 我们也可以不使用过滤器,而是使用拦截器对 Hystrix缓存上下文进行初始化。注意拦截器类和拦截器注册配置类都要与工程中的 springboot 主类放在同一个包中。

7.1 拦截器代码

package com.example.server1;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;
@Component
public class HystrixInterceptor implements HandlerInterceptor {
Integer i = 0;
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,Object handler) throws Exception {
System.out.println("执行控制器之前执行拦截器");
if (i==0) {
HystrixRequestContext.initializeContext();
//return true;
i++;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("执行控制器之后执行拦截器");
//HystrixRequestContext.initializeContext();
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,Object handler ,
Exception ex) throws Exception {
System.out.println("前端控制器之后执行拦截器");
}
}

7.2 拦截器注册配置类代码

package com.example.server1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.example.server1.HystrixInterceptor;
@SpringBootConfiguration
public class MySpringMVCConfig extends WebMvcConfigurerAdapter {
@Autowired
private HystrixInterceptor hystrixInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(hystrixInterceptor).addPathPatterns("/**");
}
}

 

最后

以上就是敏感茉莉为你收集整理的使用 @CacheResult 注解 使用Hystrix 请求缓存的全部内容,希望文章能够帮你解决使用 @CacheResult 注解 使用Hystrix 请求缓存所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(55)

评论列表共有 0 条评论

立即
投稿
返回
顶部