Spring Cloud系列之Commons - 2. 服务发现 - 如何通过配置文件配置服务实例?(下)

简介: Spring Cloud系列之Commons - 2. 服务发现 - 如何通过配置文件配置服务实例?(下)

我们可以直接通过 uri 配置,也可以具体配置其中的 host,port 和 isSecure,两者是等价的。例如:


spring:
  cloud:
    discovery:
      client:
        # SimpleDiscoveryClient与SimpleReactiveDiscoveryClient的配置
        simple:
          instances:
            #微服务1
            service1:
              #实例1
              - host: instance1 #地址
                port: 8080 #端口


等价于

spring:
  cloud:
    discovery:
      client:
        # SimpleDiscoveryClient与SimpleReactiveDiscoveryClient的配置
        simple:
          instances:
            #微服务1
            service1:
              #实例1
              - uri: http://instance1:8080


instanceId 不一定需要指定,serviceId 会根据实例配置的上一级取,就算自己配置了,例如:

spring:
  cloud:
    discovery:
      client:
        # SimpleDiscoveryClient与SimpleReactiveDiscoveryClient的配置
        simple:
          instances:
            #微服务1
            service1:
              #实例1
              - host: instance1 #地址
                port: 8080 #端口
                serviceId: service2 #无效,实际还是service1


serviceId 还是实际合理的那个,也就是 service1。

这些机制在后面的源码分析就会理解了。 我们的测试代码会用到 Spring Boot 的事件机制,也就是在 ApplicationContext 到某一生命周期的时候,这些事件会被发布出来,由实现了对应事件的ApplicationListener接口的 Bean 消费,Spring boot 中,事件主要包括:


  • ApplicationStartingEvent:这个是spring boot应用一开始启动时,发出的事件,只是用来标识,应用开始启动了,一般没什么用
  • ApplicationEnvironmentPreparedEvent:这个是在创建好Environment(通过上下文配置,判断到底创建StandardServletEnvironment(针对Servlet环境),StandardReactiveWebEnvironment(针对Reactive环境)还是StandardEnvironment(针对无servlet环境))之后发出的事件。
  • ApplicationContextInitializedEvent: 这个是在创建好Context并调用ApplicationContextInitializer初始化context之后发布这个事件,在加载bean信息之前
  • ApplicationPreparedEvent:加载bean信息之后,但是还没有创建bean的时候,发步这个事件。这个事件是和调用ApplicationContextAware设置ApplicationContext一起进行的,可以看出,setApplicationContext方法里面不能去获取bean,因为bean可能还没有初始化完成
  • ApplicationStartedEvent: 加载初始化各种需要的bean并依赖注入之后,在运行ApplicationRunner做一些用户自定义的初始化操作之前,会发布这个事件。
  • ApplicationReadyEvent:运行ApplicationRunner做一些用户自定义的初始化操作之后,会发布这个事件。


我们使用ApplicationReadyEventApplicationListener确保所有的DiscoveryClient都初始化完成并可以使用作为测试类。


编写测试类: TestSimpleDiscoveryClient


/**
 * 通过消费 ApplicationReadyEvent 来确保 DiscoveryClient 初始化完成并可用
 */
@Slf4j
@Component
public class TestSimpleDiscoveryClient implements ApplicationListener<ApplicationReadyEvent> {
    /**
     * 初始化的方法返回类型是 DiscoveryClient 并且不是 Primary,这里只能通过 @Resource 自动装载不能通过 @Autowired
     * 这里不排除以后返回类型修改为 SimpleDiscoveryClient 的可能性
     * @see org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration
     */
    @Resource
    private SimpleDiscoveryClient simpleDiscoveryClient;
    @Override
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
        List<String> services = simpleDiscoveryClient.getServices();
        services.forEach(serviceId -> {
            log.info("{}: {}", serviceId, simpleDiscoveryClient.getInstances(serviceId));
        });
    }
}


TestSimpleReactiveDiscoveryClient


/**
 * 通过消费 ApplicationReadyEvent 来确保 DiscoveryClient 初始化完成并可用
 */
@Slf4j
@Component
public class TestSimpleReactiveDiscoveryClient implements ApplicationListener<ApplicationReadyEvent> {
    @Autowired
    private SimpleReactiveDiscoveryClient simpleReactiveDiscoveryClient;
    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        simpleReactiveDiscoveryClient.getServices().subscribe(serviceId -> {
            simpleReactiveDiscoveryClient.getInstances(serviceId).collect(Collectors.toList()).subscribe(serviceInstances -> {
                log.info("{}: {}", serviceId, serviceInstances);
            });
        });
    }
}


启动类:DiscoveryClientMain


@SpringBootApplication
public class DiscoveryClientMain {
    public static void main(String[] args) {
        SpringApplication.run(DiscoveryClientMain.class, args);
    }
}


启动后,可以看到日志:


2021-01-19 09:38:05.646  INFO 6168 --- [           main] .h.s.c.i.s.d.s.TestSimpleDiscoveryClient : service2: [DefaultServiceInstance{instanceId='instance3:80', serviceId='service2', host='instance3', port=80, secure=false, metadata={}}, DefaultServiceInstance{instanceId='null', serviceId='service2', host='instance4', port=8080, secure=true, metadata={}}]
2021-01-19 09:38:05.647  INFO 6168 --- [           main] .h.s.c.i.s.d.s.TestSimpleDiscoveryClient : service1: [DefaultServiceInstance{instanceId='instance:8080', serviceId='service1', host='instance1', port=8080, secure=false, metadata={}}, DefaultServiceInstance{instanceId='null', serviceId='service1', host='instance2', port=443, secure=true, metadata={}}]
2021-01-19 09:38:05.913  INFO 6168 --- [           main] .s.d.s.TestSimpleReactiveDiscoveryClient : service2: [DefaultServiceInstance{instanceId='instance3:80', serviceId='service2', host='instance3', port=80, secure=false, metadata={}}, DefaultServiceInstance{instanceId='null', serviceId='service2', host='instance4', port=8080, secure=true, metadata={}}]
2021-01-19 09:38:05.913  INFO 6168 --- [           main] .s.d.s.TestSimpleReactiveDiscoveryClient : service1: [DefaultServiceInstance{instanceId='instance:8080', serviceId='service1', host='instance1', port=8080, secure=false, metadata={}}, DefaultServiceInstance{instanceId='null', serviceId='service1', host='instance2', port=443, secure=true, metadata={}}]


相关文章
|
15天前
|
Java Spring
【Spring】方法注解@Bean,配置类扫描路径
@Bean方法注解,如何在同一个类下面定义多个Bean对象,配置扫描路径
144 73
|
2月前
|
Java 开发者 微服务
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
70 0
|
17天前
|
XML Java 数据格式
使用idea中的Live Templates自定义自动生成Spring所需的XML配置文件格式
本文介绍了在使用Spring框架时,如何通过创建`applicationContext.xml`配置文件来管理对象。首先,在resources目录下新建XML配置文件,并通过IDEA自动生成部分配置。为完善配置,特别是添加AOP支持,可以通过IDEA的Live Templates功能自定义XML模板。具体步骤包括:连续按两次Shift搜索Live Templates,配置模板内容,输入特定前缀(如spring)并按Tab键即可快速生成完整的Spring配置文件。这样可以大大提高开发效率,减少重复工作。
使用idea中的Live Templates自定义自动生成Spring所需的XML配置文件格式
|
15天前
|
Java Spring
【Spring配置相关】启动类为Current File,如何更改
问题场景:当我们切换类的界面的时候,重新启动的按钮是灰色的,不能使用,并且只有一个Current File 项目,下面介绍两种方法来解决这个问题。
|
15天前
|
Java Spring
【Spring配置】idea编码格式导致注解汉字无法保存
问题一:对于同一个项目,我们在使用idea的过程中,使用汉字注解完后,再打开该项目,汉字变成乱码问题二:本来a项目中,汉字注解调试好了,没有乱码了,但是创建出来的新的项目,写的注解又成乱码了。
|
15天前
|
Java Spring
【Spring配置】创建yml文件和properties或yml文件没有绿叶
本文主要针对,一个项目中怎么创建yml和properties两种不同文件,进行配置,和启动类没有绿叶标识进行解决。
|
24天前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
82 14
|
21天前
|
XML Java 数据格式
Spring容器Bean之XML配置方式
通过对以上内容的掌握,开发人员可以灵活地使用Spring的XML配置方式来管理应用程序的Bean,提高代码的模块化和可维护性。
57 6
|
3月前
|
Java API Spring
在 Spring 配置文件中配置 Filter 的步骤
【10月更文挑战第21天】在 Spring 配置文件中配置 Filter 是实现请求过滤的重要手段。通过合理的配置,可以灵活地对请求进行处理,满足各种应用需求。还可以根据具体的项目要求和实际情况,进一步深入研究和优化 Filter 的配置,以提高应用的性能和安全性。
|
23天前
|
XML Java 数据格式
🌱 深入Spring的心脏:Bean配置的艺术与实践 🌟
本文深入探讨了Spring框架中Bean配置的奥秘,从基本概念到XML配置文件的使用,再到静态工厂方式实例化Bean的详细步骤,通过实际代码示例帮助读者更好地理解和应用Spring的Bean配置。希望对你的Spring开发之旅有所助益。
89 3