学习分享,共勉
这里是小编拿到的学习资源,其中包括“中高级Java开发面试高频考点题笔记300道.pdf”和“Java核心知识体系笔记.pdf”文件分享,内容丰富,囊括了JVM、锁、并发、Java反射、Spring原理、微服务、Zookeeper、数据库、数据结构等大量知识点。同时还有Java进阶学习的知识笔记脑图(内含大量学习笔记)!
资料整理不易,读者朋友可以转发分享下!
Java核心知识体系笔记.pdf
中高级Java开发面试高频考点题笔记300道.pdf
架构进阶面试专题及架构学习笔记脑图
Java架构进阶学习视频分享
SERVICE-PRODUCT
中的/product/{id}
接口源码如下:
/\*\*
\* @author :浦江之猿
\*/
@RestController
@RequestMapping("/product")
public class ProductController {
@Autowired
ProductService productService;
@GetMapping(value = "/{id}")
public Product findById(@PathVariable Long id) {
Product product = productService.findById(id);
product.setName(product.getName() + "1");
return product;
}
@GetMapping(value = "/{id}/{price}")
public Product findByIdAndPrice(@PathVariable Long id, @PathVariable BigDecimal price) {
Product product = productService.findProductByIdAndPrice(id, price);
product.setName(product.getName() + "1");
return product;
}
@PostMapping(value = "/addProduct")
public Product addProduct(@RequestParam String name, @RequestParam BigDecimal price) {
Product product = new Product();
product.setName(name);
product.setPrice(price);
return productService.addProduct(product);
}
@PutMapping(value = "/updateProduct")
public void updateProduct(@RequestParam Long id, @RequestParam BigDecimal price) {
Product product = productService.findById(id);
product.setPrice(price);
productService.updateProduct(product);
}
@DeleteMapping(value = "/deleteProduct/{id}")
public void deleteProduct(@PathVariable Long id) {
productService.deleteById(id);
}
}
在Controller 中调用服务
定义一个Controller 来调用上面的service层,可以发现service层只有接口,没有接口的实现。
/\*\*
\* @author :浦江之猿
\*/
@RestController
public class OrderController {
@Resource
OrderService orderService;
@GetMapping(value = "/buy/{id}")
public Product findById(@PathVariable("id") Long id) {
return orderService.findById(id);
}
}
添加配置文件
因为OpenFeign需要获取服务提供者且自己本身也是一个服务,因此配置文件中需要添加eureka。
server:
port: 9007 #端口
spring:
favicon:
enabled: false
application:
name: service-openfeign #服务名称
#配置eureka server
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
#注册到两个eureka上
defaultZone: http://localhost:9005/eureka/,http://localhost:9006/eureka/
结果
到这,整个OpenFeign客户端就搭建好了,浏览器中输入http://localhost:9007/buy/1
。其结果如下:
{
"id": 1,
"name": "apple2",
"price": 8000.00
}
Ok,整个服务就打通了,接下来看看OpenFeign是如何实现负载均衡功能和熔断功能的。
实现负载均衡功能
在声明服务创建接口时,就已经添加了负载均衡功能(通过@RequestMapping注解,可以理解为OpenFeign内置了Ribbon),只是这里的负载均衡算法用的是默认算法(轮询)。如果需要改变负载算法,则需要定义一个配置类,然后在配置类中注入需要的算法。以改成随机算法为例:
/\*\*
\* @author :浦江之猿
\* @date :Created in 2022/5/31 22:02
\*/
@Configuration
public class OpenFeignConfig {
@Bean
public IRule getIRule() {
return new RandomRule();
}
}
关于负载均衡的其算法可以参考博文SpringCloud实战之Ribbon
实现熔断功能
OpenFeign整合了Hystrix,所有熔断原理一样,当出现异常时直接进行服务降级,回调异常处理函数。但是这里的异常处理函数与接口一一对应,不是太好理解,可以看下面的例子。OpenFeign中实现熔断需要两步:
配置熔断开关
配置文件中将熔断开关打开
#熔断开关打开
feign:
hystrix:
enabled: true
实现回调函数
为了更好的解释异常处理函数与接口一一对应,再声明一个服务,即在OrderService接口中再绑定一个服务提供者提供的接口。
@GetMapping(value = "/product/{id}/{price}")
public Product findByIdAndPrice(@PathVariable Long id, @PathVariable BigDecimal price);
接下来实现OrderService接口,实现类中实现的每个方法就是此接口对应的熔断回调函数。注意:@Component
注解一定要解,不然启动失败,报找不到实例异常。
@Component
public class OrderServiceImpl implements OrderService {
@Override
public Product findById(Long id) {
return handleBreakCircuit(id, "A fake product from findById");
}
@Override
public Product findByIdAndPrice(Long id, BigDecimal price) {
return handleBreakCircuit(id, "A fake product from findByIdAndPrice");
}
public Product handleBreakCircuit(Long id, String des) {
Product product = new Product();
product.setId(0L);
product.setName(des);
product.setPrice(new BigDecimal(0));
return product;
}
}
最后需要在声明接口中回调OrderServiceImple中的函数,只需要在@FeignClient
注解添加fallback
属性即可,完整的OrderService如下:
@FeignClient(value = "SERVICE-PRODUCT", fallback = OrderServiceImpl.class )
public interface OrderService {
@GetMapping(value = "/product/{id}")
public Product findById(@PathVariable("id") Long id);
@GetMapping(value = "/product/{id}/{price}")
public Product findByIdAndPrice(@PathVariable Long id, @PathVariable BigDecimal price);
}
相应的,在服务提供者1中针对findById
选择制造一个超时(默认为1000ms),服务提供者2正常。
@GetMapping(value = "/{id}")
public Product findById(@PathVariable Long id) {
Product product = productService.findById(id);
//故意制造一个超时
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
product.setName(product.getName() + "1");
return product;
}
最终结果在以下两者之间随机切换:
//服务提供者1返回的结果
{
"id": 0,
"name": "A fake product from findById",
"price": 0
}
//服务提供者2返回的结果
{
"id": 1,
"name": "apple2",
"price": 8000.00
}
获取异常信息
通过fallback
可以回调服务降级函数 ,但时当服务提供抛出异常后没法获取异常信息。OpenFeign中提供了fallbackFactory
属性,在fallbackFactory中实现实现OrderService接口,就可以获取异常信息。用下面的类代替上面的OrderServiceImpl不仅能够回调降级函数 ,还能获取异常信息。
//注解不能少
@Component
public class OrderFallbackFactory implements FallbackFactory<OrderService> {
@Override
public OrderService create(Throwable arg0) {
# 最后
按照上面的过程,4个月的时间刚刚好。当然Java的体系是很庞大的,还有很多更高级的技能需要掌握,但不要着急,这些完全可以放到以后工作中边用别学。
学习编程就是一个由混沌到有序的过程,所以你在学习过程中,如果一时碰到理解不了的知识点,大可不必沮丧,更不要气馁,这都是正常的不能再正常的事情了,不过是“人同此心,心同此理”的暂时而已。
“**道路是曲折的,前途是光明的**!”
![](https://img-blog.csdnimg.cn/img_convert/56584d9ebf2939d1b1369a9ebd6967a5.webp?x-oss-process=image/format,png)
![](https://img-blog.csdnimg.cn/img_convert/c3d97433104a530ddb6ccda3dfc7ba32.webp?x-oss-process=image/format,png)
> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)收录**
**[需要这份系统化的资料的朋友,可以点击这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**
是曲折的,前途是光明的**!”
[外链图片转存中...(img-77UlnBvw-1715541524195)]
[外链图片转存中...(img-qv0ZzJ5M-1715541524195)]
> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)收录**
**[需要这份系统化的资料的朋友,可以点击这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**