public String orders(){
System.out.println(“Order 服务端口是:”+port);
return "Order Services … ";
}
}
然后我们可以分别启动两个Order服务,端口分别设置为 8081和8082
User服务作为调用用Order服务的客户端。也是我们要重点介绍【Ribbon】的服务。同样创建一个SpringBoot项目,添加相关的依赖
<?xml version="1.0" encoding="UTF-8"?><project xmlns=“http://maven.apache.org/POM/4.0.0” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd”>
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.3.9.RELEASE
com.bobo.springcloud
spring-cloud-user-service2
0.0.1-SNAPSHOT
spring-cloud-user-service2
Demo project for Spring Boot
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR10</spring-cloud.version>
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-netflix-ribbon
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
org.springframework.boot
spring-boot-maven-plugin
然后在属性文件中配置相关信息
spring.application.name=spring-cloud-user-service
spring-cloud-order-service.ribbon.listOfServers=localhost:8081,localhost:8082
然后创建自定义的Controller来实现服务的调用
@RestController
public class UserController {
@Autowired
public RestTemplate restTemplate;
@Autowired
LoadBalancerClient loadBalancerClient;
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
@GetMapping(“/users”)
public String users(){
ServiceInstance choose = loadBalancerClient.choose(“spring-cloud-order-service”);
String url = String.format(“http://%s:%s”,choose.getHost(),choose.getPort()+“/orders”);
//return restTemplate.getForObject(url,String.class);
return restTemplate.getForObject(“http://spring-cloud-order-service/orders”,String.class);
}
}
然后启动User服务访问,可以看到【Ribbon】默认通过轮询的方式来实现了服务的调用
===========================================================================
应用比较简单,我们主要是来分析下【Ribbon】的核心原理,先来看看自动装配做了哪些事情。
Ribbon在系统启动的时候自动装配完成的设置,我们先来看看对应的spring.factories 中的配置信息吧
emsp; 所以我们要继续来看【RibbonAutoConfiguration】配置类,我们贴出【RibbonAutoConfiguration】的关键信息
@Configuration
@Conditional({RibbonAutoConfiguration.RibbonClassesConditions.class})
@RibbonClients
@AutoConfigureAfter(
name = {“org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration”}
)
// RibbonAutoConfiguration配置类注入容器后会完成 LoadBalancerAutoConfiguration 和 AsyncLoadBalancerAutoConfiguration 的注入
@AutoConfigureBefore({LoadBalancerAutoConfiguration.class, AsyncLoadBalancerAutoConfiguration.class})
@EnableConfigurationProperties({RibbonEagerLoadProperties.class, ServerIntrospectorProperties.class})
public class RibbonAutoConfiguration {
/**
-
如果IoC容器中不存在 LoadBalancerClient 类型的对象就注入一个
-
具体注入的类型为 RibbonLoadBalancerClient 对象
**/
@Bean
@ConditionalOnMissingBean({LoadBalancerClient.class})
public LoadBalancerClient loadBalancerClient() {
return new RibbonLoadBalancerClient(this.springClientFactory());
}
// 省略其他代码
通过源码查看我们知道在SpringBoot项目启动的时候完成了【LoadBalancerClient】对象的注入,且具体的类型为【RibbonLoadBalancerClient】,同时还会完成【LoadBalancerAutoConfiguration】这个配置类型的加载。在看【LoadBalancerAutoConfiguration】做了什么事情之前,我们先来搞清楚【@LoadBalanced】注解的作用
2.LoadBalancerAutoConfiguration
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Qualifier
public @interface LoadBalanced {
}
【@LoadBalanced】本质上就是一个【@Qualifier】注解。作用就是标记,我们通过案例来演示说明。
定义一个简单的【User】类
public class User {
String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return “User{” +
“name='” + name + ‘’’ +
‘}’;
}
}
然后定义一个Java配置类,有两个添加了【@LoadBalanced】注解,有一个没有加。
@Configuration
public class JavaConfig {
@LoadBalanced
@Bean(“user1”)
public User user1(){
return new User(“user1”);
}
@Bean(“user2”)
public User user2(){
return new User(“user2”);
}
@LoadBalanced
@Bean(“user3”)
public User user3(){
return new User(“user3”);
}
}
然后创建我们的控制器,来测试使用
@RestController
public class UsersController {
@LoadBalanced
@Autowired
List list = Collections.emptyList();
@GetMapping(“/querys”)
public String query(){
return list.toString();
}
}
项目结构
启动SpringBoot项目后我们看效果
搞清楚了【@LoadBalanced】的作用后,我们再来看看【LoadBalancerAutoConfiguration】的配置加载做了什么事情
public class LoadBalancerAutoConfiguration {
/**
-
-
获取IoC容器中所有的被【@LoadBalanced】注解修饰的RestTemplate对象
-
这些对象保存在了一个集合中
**/
@LoadBalanced
@Autowired(required = false)
private List restTemplates = Collections.emptyList();
@Autowired(required = false)
private List transformers = Collections.emptyList();
/**
-
-
向容器中注入了 SmartInitializingSingleton 对象,并且实现了 SmartInitializingSingleton 接口中声明的
-
afterSingletonsInstantiated 方法,在该方法中 通过3 中的 RestTemplateCustomizer中定义的 customize 方法
-
实现了 RestTemplate 对象拦截器的植入
**/
@Bean
public SmartInitializingSingleton loadBalancedRestTemplateInitializerDeprecated(
final ObjectProvider<List> restTemplateCustomizers) {
return () -> restTemplateCustomizers.ifAvailable(customizers -> {
for (RestTemplate restTemplate : LoadBalancerAutoConfiguration.this.restTemplates) {
for (RestTemplateCustomizer customizer : customizers) {
customizer.customize(restTemplate);
}
}
});
}
@Bean
@ConditionalOnMissingBean
public LoadBalancerRequestFactory loadBalancerRequestFactory(
LoadBalancerClient loadBalancerClient) {
return new LoadBalancerRequestFactory(loadBalancerClient, this.transformers);
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://img-blog.csdnimg.cn/img_convert/5175707a9aac04c44703c9a64c851668.jpeg)
我的面试宝典:一线互联网大厂Java核心面试题库
以下是我个人的一些做法,希望可以给各位提供一些帮助:
整理了很长一段时间,拿来复习面试刷题非常合适,其中包括了Java基础、异常、集合、并发编程、JVM、Spring全家桶、MyBatis、Redis、数据库、中间件MQ、Dubbo、Linux、Tomcat、ZooKeeper、Netty等等,且还会持续的更新…可star一下!
283页的Java进阶核心pdf文档
Java部分:Java基础,集合,并发,多线程,JVM,设计模式
数据结构算法:Java算法,数据结构
开源框架部分:Spring,MyBatis,MVC,netty,tomcat
分布式部分:架构设计,Redis缓存,Zookeeper,kafka,RabbitMQ,负载均衡等
微服务部分:SpringBoot,SpringCloud,Dubbo,Docker
还有源码相关的阅读学习
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
非常合适,其中包括了Java基础、异常、集合、并发编程、JVM、Spring全家桶、MyBatis、Redis、数据库、中间件MQ、Dubbo、Linux、Tomcat、ZooKeeper、Netty等等,且还会持续的更新…可star一下!
[外链图片转存中…(img-7Uix3aUo-1713499706901)]
283页的Java进阶核心pdf文档
Java部分:Java基础,集合,并发,多线程,JVM,设计模式
数据结构算法:Java算法,数据结构
开源框架部分:Spring,MyBatis,MVC,netty,tomcat
分布式部分:架构设计,Redis缓存,Zookeeper,kafka,RabbitMQ,负载均衡等
微服务部分:SpringBoot,SpringCloud,Dubbo,Docker
[外链图片转存中…(img-vBZnzXwC-1713499706901)]
还有源码相关的阅读学习
[外链图片转存中…(img-0wIhZLtg-1713499706902)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!