为什么使用bean注解创建IRule,就可以定义负载均衡规则

@Bean

public IRule randomRule() {

return new RandomRule();

}

当您在Spring Cloud中定义一个IRule的Bean时,您实际上是在配置Ribbon的负载均衡规则。这个Bean会被注入到Ribbon客户端中,并在客户端发起服务调用时用于决定如何选择目标服务实例。


这里需要对注入的概念重新回顾一下:

注入==》依赖注入==》控制反转==》控制对象生成的过程不再由程序员主动定义,而是交由spring容器控制

  1. 正向的控制是通过new关键字主动的创建一个对象
    是人在控制对象的创建和销毁过程
  2. 控制反转是通过@Bean将对象注册到spring容器中,通过@Autowired将容器中的对象注入
    是spring容器在控制对象的创建和销毁过程

控制反转的案例

假设有接口A,接口实现类B,接口实现类C

接口A定义负载均衡基础规则

B实现了负载均衡-轮询

C实现了负载均衡-随机


使用new主动创建:

首先使用轮询

A test = new B();

创建了至少20个new B();在不同的位置

之后,需要修改规则为随机

此时,需要将至少20个在不同的位置的new B();更改为new C();

异常繁琐


使用控制反转:

首先使用轮询

先用@bean注解定义注册到Spring容器的接口实现类是B

复制代码
@Bean
public A test() {
    return  new B();   
}

之后,使用@Autowired将实现类出注入,创建的过程完全由spring容器控制

复制代码
@Autowired
A test;

使用了至少20个,但都是依赖注入

之后,需要修改规则为随机

此时,只需要将@Bean注册的方法修改成随机就可以了

复制代码
@Bean
public A test() {
    return  new C();   
}

补充

提问:

如何实现,当用户不定义bean时使用默认的A接口的B类,用户定义Bean返回的是什么就使用什么进行依赖注入

回答:

要实现这样的功能,你可以使用Spring框架的自动配置和条件化Bean定义。以下是一个简单的示例来说明如何实现这个需求:

定义默认实现:首先,你需要有一个默认的A接口的实现类a。

java 复制代码
public interface A {
    // ... 接口方法 ...
}

@Component
public class DefaultA implements A {
    // ... 实现方法 ...
}

在这个例子中,DefaultA类实现了A接口,并且使用了@Component注解,使其成为Spring容器中的一个Bean。

  1. 条件化用户自定义Bean:你可以使用@Conditional注解来根据条件决定是否创建某个Bean。例如,你可以检查是否存在用户自定义的A接口的实现。
java 复制代码
@Configuration
public class AConfig {

    @Bean
    @ConditionalOnMissingBean(A.class)
    public A defaultA() {
        return new DefaultA();
    }

    @Bean
    @ConditionalOnBean(A.class)
    public A userDefinedA(A a) {
        return a; // 返回用户定义的Bean
    }
}

在这个配置类中,我们定义了两个Bean。

第一个Bean defaultA会在没有其他A类型的Bean存在时被创建(即用户没有定义自己的Bean)。

第二个Bean userDefinedA则会在存在A类型的Bean时被创建,这时它会返回用户定义的Bean。

  1. 使用:现在,当用户没有定义自己的A接口实现时,Spring会注入DefaultA的实例。如果用户定义了自己的实现,Spring会注入用户定义的Bean。
java 复制代码
@Service
public class SomeService {

    private final A a;

    @Autowired
    public SomeService(A a) {
        this.a = a;
    }

    // ... 使用a的方法 ...
}

在这个例子中,SomeService的构造函数会注入一个A类型的Bean。根据用户是否定义了自己的Bean,注入的可能是DefaultA的实例或者是用户定义的Bean。

通过这种方式,你可以实现当用户不定义Bean时使用默认的A接口的a类,而用户定义Bean时则返回用户定义的内容进行依赖注入。

相关推荐
短剑重铸之日3 天前
《SpringCloud实用版》Stream + RocketMQ 实现可靠消息 & 事务消息
后端·rocketmq·springcloud·消息中间件·事务消息
没有bug.的程序员4 天前
Spring Cloud Stream:消息驱动微服务的实战与 Kafka 集成终极指南
java·微服务·架构·kafka·stream·springcloud·消息驱动
没有bug.的程序员5 天前
Spring Cloud Gateway:API网关限流与熔断实战
java·开发语言·数据库·spring boot·gateway·api·springcloud
wfsm9 天前
nacos和openfeign
springcloud
无心水9 天前
【分布式利器:腾讯TSF】11、腾讯TSF微服务框架深度对比:全面解析TSF vs Spring Cloud vs Dubbo vs Service Mesh
分布式·spring cloud·微服务·dubbo·springcloud·service mesh·分布式利器
sunnyday042610 天前
Spring Cloud Alibaba Sentinel 流量控制与熔断降级实战指南
spring boot·sentinel·springcloud
悟空码字13 天前
Spring Cloud 集成 Nacos,全面的配置中心与服务发现解决方案
java·nacos·springcloud·编程技术·后端开发
坐不住的爱码20 天前
Bootstrap和application.yml
springcloud
悟空码字20 天前
Spring Cloud Gateway实战,从零搭建API网关,构建高性能微服务统一入口
java·gateway·springcloud·编程技术·后端开发
没有bug.的程序员22 天前
Service Mesh 与 Spring Cloud 共存方案:双体系治理、平滑迁移与风险控制实战指南
云原生·springcloud·流量治理·混合架构·servicemesh·微服务迁移·技术演进