-
Notifications
You must be signed in to change notification settings - Fork 26.6k
Description
Background
Between 2020 and 2021, I frequently utilized HSF, which recommended consolidating multiple providers/consumers into a single configuration class. This approach utilized the native Spring programming style in business logic (with consumers Autowired and providers annotated with @service), effectively decoupling Spring from HSF. Upon transitioning to Dubbo 2.7.x, I noticed the absence of this mechanism. Consequently, I independently implemented related functionality within our company's internal framework. Now, with Dubbo 3.x, I observe the integration of Dubbo and HSF, where Dubbo has finally implemented the ability to configure providers and consumers in a configuration class. However, I find the current approach still lacking in conciseness. Hence, I'd like to explore the possibility of achieving even greater conciseness.
Describe the proposal
1.Consumers using field mode in configuration class:
@RpcConsumerCollector
public class RpcConsumerConfig {
@RpcConsumer(group = "demo", version = "${dubbo.provider.version:1.0.0}")
private UserRpcService userRpcService;
}This method is equivalent to the current approach of using the ReferenceBean in Dubbo 3.x, but the field approach is comparatively more concise.
2.Providers using field mode in configuration class:
@RpcProviderCollector
public class RpcProviderConfig {
// interfaceClass can be omitted
@RpcProvider(group = "demo", version = "1.0.0", interfaceClass = UserRpcService.class)
private UserRpcService userService;
}This approach is equivalent to the current method of using DubboService in Dubbo 3.x, but the field approach is relatively more concise. It avoids code like new UserRpcServiceImpl. It's worth noting that for providers, there might be cases where the same interface has multiple implementations (for different versions of RPC services). In such cases, the field type can be directly set to UserRpcServiceImpl, and interfaceClass can be specified as UserRpcService.class (interfaceClass can be omitted when the implementation class implements only one interface).
3.Collectors:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Component
public @interface RpcProviderCollector {
String version() default "";
String group() default "";
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Component
public @interface RpcConsumerCollector {
String version() default "";
String group() default "";
}As mentioned earlier, while it's advantageous to manage consumers and providers centrally, there are times when you don't want to put all providers/consumers together. In such cases, collectors can be used. For example, you can place the consumers of application A in ARpcConsumerConfig and the consumers of application B in BRpcConsumerConfig. Then, you can directly add @RpcConsumerCollector to the class, specifying group and version. The fields inside will inherit the group and version from @RpcConsumerCollector by default, ideally achieving a very concise program.
@RpcConsumerCollector(group = "demo", version = "${dubbo.consumer.version:1.0.0}")
public class RpcConsumerConfig {
private UserRpcService userRpcService;
private UserRpcService1 userRpcService1;
private UserRpcService2 userRpcService2;
}Goals
- Introducing new methods to simplify code implementation, not limited to the use of fields
Non-Goals
- Replace the original method usage
Replenish
This program has been running in our company for more than 2 years with no obvious side effects.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status