0
# Spring Boot Integration
1
2
Apache Dubbo provides comprehensive Spring Boot integration through auto-configuration, annotations, and properties-based configuration. This enables seamless integration with Spring Boot applications and Spring ecosystem components.
3
4
## Capabilities
5
6
### Auto-Configuration
7
8
Dubbo Spring Boot starter provides automatic configuration and component registration.
9
10
```java { .api }
11
/**
12
* Main Dubbo auto-configuration class
13
*/
14
@Configuration
15
@ConditionalOnProperty(prefix = DUBBO_PREFIX, name = "enabled", matchIfMissing = true)
16
@ConditionalOnClass(DubboBootstrap.class)
17
@EnableConfigurationProperties({DubboConfigurationProperties.class})
18
@Import({DubboConfigConfiguration.class, DubboServiceConfiguration.class})
19
public class DubboAutoConfiguration {
20
21
@Bean
22
@ConditionalOnMissingBean
23
public DubboBootstrap dubboBootstrap() {
24
return DubboBootstrap.getInstance();
25
}
26
27
@Bean
28
@ConditionalOnProperty(prefix = DUBBO_APPLICATION_PREFIX, name = "name")
29
@ConditionalOnMissingBean
30
public ApplicationConfig applicationConfig(DubboConfigurationProperties properties) {
31
return properties.getApplication();
32
}
33
34
@Bean
35
@ConditionalOnMissingBean
36
public DubboLifecycleComponentApplicationListener dubboLifecycleComponentApplicationListener() {
37
return new DubboLifecycleComponentApplicationListener();
38
}
39
}
40
41
/**
42
* Dubbo configuration properties binding
43
*/
44
@ConfigurationProperties(prefix = DUBBO_PREFIX)
45
public class DubboConfigurationProperties {
46
public static final String DUBBO_PREFIX = "dubbo";
47
48
private ApplicationConfig application = new ApplicationConfig();
49
private ModuleConfig module = new ModuleConfig();
50
private RegistryConfig registry = new RegistryConfig();
51
private ProtocolConfig protocol = new ProtocolConfig();
52
private MonitorConfig monitor = new MonitorConfig();
53
private ProviderConfig provider = new ProviderConfig();
54
private ConsumerConfig consumer = new ConsumerConfig();
55
private ConfigCenterConfig configCenter = new ConfigCenterConfig();
56
private MetadataReportConfig metadataReport = new MetadataReportConfig();
57
private MetricsConfig metrics = new MetricsConfig();
58
private SslConfig ssl = new SslConfig();
59
60
// Multiple configurations support
61
private Map<String, ApplicationConfig> applications = new HashMap<>();
62
private Map<String, ModuleConfig> modules = new HashMap<>();
63
private Map<String, RegistryConfig> registries = new HashMap<>();
64
private Map<String, ProtocolConfig> protocols = new HashMap<>();
65
private Map<String, ProviderConfig> providers = new HashMap<>();
66
private Map<String, ConsumerConfig> consumers = new HashMap<>();
67
68
// Getters and setters...
69
public ApplicationConfig getApplication() { return application; }
70
public void setApplication(ApplicationConfig application) { this.application = application; }
71
72
public Map<String, RegistryConfig> getRegistries() { return registries; }
73
public void setRegistries(Map<String, RegistryConfig> registries) { this.registries = registries; }
74
75
public Map<String, ProtocolConfig> getProtocols() { return protocols; }
76
public void setProtocols(Map<String, ProtocolConfig> protocols) { this.protocols = protocols; }
77
}
78
```
79
80
### Enable Dubbo Annotation
81
82
Main annotation for enabling Dubbo functionality in Spring applications.
83
84
```java { .api }
85
/**
86
* Enable Dubbo functionality annotation
87
*/
88
@Target(ElementType.TYPE)
89
@Retention(RetentionPolicy.RUNTIME)
90
@Inherited
91
@Documented
92
@Import(DubboComponentScanRegistrar.class)
93
public @interface EnableDubbo {
94
/**
95
* Base packages to scan for Dubbo components
96
* @return Base package names
97
*/
98
String[] scanBasePackages() default {};
99
100
/**
101
* Base package classes to scan for Dubbo components
102
* @return Base package classes
103
*/
104
Class<?>[] scanBasePackageClasses() default {};
105
106
/**
107
* Multiple registries support
108
* @return Whether to support multiple registries
109
*/
110
boolean multipleConfig() default true;
111
}
112
113
/**
114
* Dubbo component scan registrar
115
*/
116
public class DubboComponentScanRegistrar implements ImportBeanDefinitionRegistrar {
117
@Override
118
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
119
BeanDefinitionRegistry registry) {
120
// Register Dubbo component scanners
121
Set<String> packagesToScan = getPackagesToScan(importingClassMetadata);
122
registerServiceAnnotationBeanPostProcessor(packagesToScan, registry);
123
registerReferenceAnnotationBeanPostProcessor(registry);
124
}
125
}
126
```
127
128
**Usage Examples:**
129
130
```java
131
@SpringBootApplication
132
@EnableDubbo(scanBasePackages = "com.example.service")
133
public class DubboProviderApplication {
134
public static void main(String[] args) {
135
SpringApplication.run(DubboProviderApplication.class, args);
136
}
137
}
138
139
// Alternative with base package classes
140
@EnableDubbo(scanBasePackageClasses = {ServiceConfig.class, ReferenceConfig.class})
141
public class DubboConfiguration {
142
}
143
```
144
145
### Service Provider Annotation
146
147
Annotation for marking Spring beans as Dubbo service providers.
148
149
```java { .api }
150
/**
151
* Dubbo service provider annotation
152
*/
153
@Documented
154
@Retention(RetentionPolicy.RUNTIME)
155
@Target({ElementType.TYPE})
156
@Inherited
157
public @interface DubboService {
158
/** Service interface class */
159
Class<?> interfaceClass() default void.class;
160
161
/** Service interface name */
162
String interfaceName() default "";
163
164
/** Service version */
165
String version() default "";
166
167
/** Service group */
168
String group() default "";
169
170
/** Service path */
171
String path() default "";
172
173
/** Export flag */
174
boolean export() default true;
175
176
/** Service token */
177
String token() default "";
178
179
/** Service deprecated flag */
180
boolean deprecated() default false;
181
182
/** Service dynamic flag */
183
boolean dynamic() default true;
184
185
/** Access log */
186
String accesslog() default "";
187
188
/** Execute limit */
189
int executes() default -1;
190
191
/** Registration flag */
192
boolean register() default true;
193
194
/** Service weight */
195
int weight() default -1;
196
197
/** Document URL */
198
String document() default "";
199
200
/** Service delay */
201
int delay() default -1;
202
203
/** Service tags */
204
String tag() default "";
205
206
/** Service timeout (ms) */
207
int timeout() default -1;
208
209
/** Service retry times */
210
int retries() default -1;
211
212
/** Load balance strategy */
213
String loadbalance() default "";
214
215
/** Enable async invocation */
216
boolean async() default false;
217
218
/** Protocol names */
219
String[] protocol() default {};
220
221
/** Monitor */
222
String monitor() default "";
223
224
/** Validation */
225
String validation() default "";
226
227
/** Compression */
228
String compression() default "";
229
230
/** Serialization */
231
String serialization() default "";
232
233
/** Cache */
234
String cache() default "";
235
236
/** Filter */
237
String[] filter() default {};
238
239
/** Listener */
240
String[] listener() default {};
241
242
/** Parameters */
243
Parameter[] parameters() default {};
244
245
/** Application bean name */
246
String application() default "";
247
248
/** Module bean name */
249
String module() default "";
250
251
/** Provider bean name */
252
String provider() default "";
253
254
/** Protocol bean names */
255
String[] protocols() default {};
256
257
/** Monitor bean name */
258
String[] monitors() default {};
259
260
/** Registry bean names */
261
String[] registries() default {};
262
}
263
264
/**
265
* Parameter annotation for service configuration
266
*/
267
@Documented
268
@Retention(RetentionPolicy.RUNTIME)
269
@Target({ElementType.ANNOTATION_TYPE})
270
public @interface Parameter {
271
String key();
272
String value();
273
}
274
```
275
276
**Usage Examples:**
277
278
```java
279
// Basic service provider
280
@DubboService
281
public class GreeterServiceImpl implements GreeterService {
282
@Override
283
public String sayHello(String name) {
284
return "Hello, " + name + "!";
285
}
286
}
287
288
// Advanced service provider configuration
289
@DubboService(
290
version = "1.0.0",
291
group = "production",
292
timeout = 5000,
293
retries = 2,
294
loadbalance = "roundrobin",
295
protocol = {"dubbo", "rest"},
296
filter = {"validation", "cache"},
297
parameters = {
298
@Parameter(key = "cache.size", value = "1000"),
299
@Parameter(key = "validation.enabled", value = "true")
300
}
301
)
302
public class UserServiceImpl implements UserService {
303
@Override
304
public User getUserById(Long id) {
305
// Implementation
306
}
307
}
308
309
// Service with specific registries
310
@DubboService(registries = {"registry1", "registry2"})
311
public class PaymentServiceImpl implements PaymentService {
312
// Implementation
313
}
314
```
315
316
### Service Consumer Annotation
317
318
Annotation for injecting Dubbo service references into Spring beans.
319
320
```java { .api }
321
/**
322
* Dubbo service reference annotation
323
*/
324
@Documented
325
@Retention(RetentionPolicy.RUNTIME)
326
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
327
public @interface DubboReference {
328
/** Service interface class */
329
Class<?> interfaceClass() default void.class;
330
331
/** Service interface name */
332
String interfaceName() default "";
333
334
/** Service version */
335
String version() default "";
336
337
/** Service group */
338
String group() default "";
339
340
/** Service URL */
341
String url() default "";
342
343
/** Client type */
344
String client() default "";
345
346
/** Generic service */
347
String generic() default "";
348
349
/** Injvm */
350
boolean injvm() default true;
351
352
/** Check */
353
boolean check() default true;
354
355
/** Init */
356
boolean init() default false;
357
358
/** Lazy */
359
boolean lazy() default false;
360
361
/** Sticky */
362
boolean sticky() default false;
363
364
/** Reconnect */
365
String reconnect() default "";
366
367
/** Stub */
368
String stub() default "";
369
370
/** Proxy */
371
String proxy() default "";
372
373
/** Cluster */
374
String cluster() default "";
375
376
/** Connections */
377
int connections() default -1;
378
379
/** Callbacks */
380
int callbacks() default -1;
381
382
/** On connect */
383
String onconnect() default "";
384
385
/** On disconnect */
386
String ondisconnect() default "";
387
388
/** Owner */
389
String owner() default "";
390
391
/** Layer */
392
String layer() default "";
393
394
/** Retry times */
395
int retries() default -1;
396
397
/** Load balance */
398
String loadbalance() default "";
399
400
/** Async */
401
boolean async() default false;
402
403
/** Active limit */
404
int actives() default -1;
405
406
/** Sent */
407
boolean sent() default true;
408
409
/** Mock */
410
String mock() default "";
411
412
/** Validation */
413
String validation() default "";
414
415
/** Timeout */
416
int timeout() default -1;
417
418
/** Cache */
419
String cache() default "";
420
421
/** Filter */
422
String[] filter() default {};
423
424
/** Listener */
425
String[] listener() default {};
426
427
/** Parameters */
428
Parameter[] parameters() default {};
429
430
/** Application bean name */
431
String application() default "";
432
433
/** Module bean name */
434
String module() default "";
435
436
/** Consumer bean name */
437
String consumer() default "";
438
439
/** Monitor bean name */
440
String monitor() default "";
441
442
/** Registry bean names */
443
String[] registries() default {};
444
445
/** Protocol */
446
String protocol() default "";
447
}
448
```
449
450
**Usage Examples:**
451
452
```java
453
// Basic service consumer
454
@RestController
455
public class UserController {
456
457
@DubboReference
458
private UserService userService;
459
460
@GetMapping("/users/{id}")
461
public User getUser(@PathVariable Long id) {
462
return userService.getUserById(id);
463
}
464
}
465
466
// Advanced reference configuration
467
@Service
468
public class OrderService {
469
470
@DubboReference(
471
version = "1.0.0",
472
group = "production",
473
timeout = 3000,
474
retries = 2,
475
loadbalance = "leastactive",
476
cluster = "failover",
477
async = true,
478
check = false
479
)
480
private PaymentService paymentService;
481
482
@DubboReference(
483
url = "dubbo://localhost:20880/InventoryService",
484
timeout = 5000
485
)
486
private InventoryService inventoryService;
487
488
public void createOrder(Order order) {
489
// Use injected services
490
paymentService.processPayment(order.getPayment());
491
inventoryService.reserveItems(order.getItems());
492
}
493
}
494
495
// Method injection
496
@Component
497
public class NotificationService {
498
499
private EmailService emailService;
500
501
@DubboReference(version = "2.0.0")
502
public void setEmailService(EmailService emailService) {
503
this.emailService = emailService;
504
}
505
}
506
```
507
508
### Configuration Properties
509
510
Spring Boot configuration properties for Dubbo settings.
511
512
```java { .api }
513
/**
514
* Application properties configuration mapping
515
*/
516
public class DubboConfigurationProperties {
517
518
// Application configuration
519
@NestedConfigurationProperty
520
private ApplicationConfig application = new ApplicationConfig();
521
522
// Protocol configurations
523
private Map<String, ProtocolConfig> protocols = new HashMap<>();
524
525
// Registry configurations
526
private Map<String, RegistryConfig> registries = new HashMap<>();
527
528
// Provider configurations
529
private Map<String, ProviderConfig> providers = new HashMap<>();
530
531
// Consumer configurations
532
private Map<String, ConsumerConfig> consumers = new HashMap<>();
533
534
// Configuration center
535
@NestedConfigurationProperty
536
private ConfigCenterConfig configCenter = new ConfigCenterConfig();
537
538
// Metadata report
539
@NestedConfigurationProperty
540
private MetadataReportConfig metadataReport = new MetadataReportConfig();
541
542
// Metrics configuration
543
@NestedConfigurationProperty
544
private MetricsConfig metrics = new MetricsConfig();
545
546
// SSL configuration
547
@NestedConfigurationProperty
548
private SslConfig ssl = new SslConfig();
549
550
// Tracing configuration
551
@NestedConfigurationProperty
552
private TracingConfig tracing = new TracingConfig();
553
}
554
```
555
556
**Configuration Examples:**
557
558
```properties
559
# Application configuration
560
dubbo.application.name=my-dubbo-app
561
dubbo.application.version=1.0.0
562
dubbo.application.owner=development-team
563
dubbo.application.organization=my-company
564
565
# Protocol configuration
566
dubbo.protocol.name=dubbo
567
dubbo.protocol.port=20880
568
dubbo.protocol.threads=200
569
dubbo.protocol.serialization=hessian2
570
571
# Multiple protocols
572
dubbo.protocols.dubbo.name=dubbo
573
dubbo.protocols.dubbo.port=20880
574
dubbo.protocols.rest.name=rest
575
dubbo.protocols.rest.port=8080
576
dubbo.protocols.rest.server=netty
577
578
# Registry configuration
579
dubbo.registry.address=zookeeper://127.0.0.1:2181
580
dubbo.registry.timeout=5000
581
dubbo.registry.check=true
582
583
# Multiple registries
584
dubbo.registries.zk1.address=zookeeper://127.0.0.1:2181
585
dubbo.registries.zk1.group=dubbo
586
dubbo.registries.nacos1.address=nacos://127.0.0.1:8848
587
dubbo.registries.nacos1.group=DEFAULT_GROUP
588
589
# Provider defaults
590
dubbo.provider.timeout=3000
591
dubbo.provider.retries=2
592
dubbo.provider.loadbalance=roundrobin
593
594
# Consumer defaults
595
dubbo.consumer.timeout=5000
596
dubbo.consumer.retries=3
597
dubbo.consumer.check=false
598
599
# Configuration center
600
dubbo.config-center.address=zookeeper://127.0.0.1:2181
601
dubbo.config-center.group=dubbo
602
dubbo.config-center.check=true
603
604
# Metrics
605
dubbo.metrics.enabled=true
606
dubbo.metrics.port=9090
607
dubbo.metrics.protocol=prometheus
608
609
# SSL/TLS
610
dubbo.ssl.enabled=true
611
dubbo.ssl.client-key-cert-chain-path=client.crt
612
dubbo.ssl.client-private-key-path=client.key
613
dubbo.ssl.client-trust-cert-collection-path=ca.crt
614
615
# QoS
616
dubbo.application.qos-enable=true
617
dubbo.application.qos-port=22222
618
dubbo.application.qos-accept-foreign-ip=false
619
```
620
621
YAML configuration:
622
623
```yaml
624
dubbo:
625
application:
626
name: my-dubbo-app
627
version: 1.0.0
628
owner: development-team
629
qos-enable: true
630
qos-port: 22222
631
632
protocols:
633
dubbo:
634
name: dubbo
635
port: 20880
636
threads: 200
637
rest:
638
name: rest
639
port: 8080
640
server: netty
641
642
registries:
643
zk1:
644
address: zookeeper://127.0.0.1:2181
645
timeout: 5000
646
check: true
647
nacos1:
648
address: nacos://127.0.0.1:8848
649
group: DEFAULT_GROUP
650
651
provider:
652
timeout: 3000
653
retries: 2
654
loadbalance: roundrobin
655
656
consumer:
657
timeout: 5000
658
retries: 3
659
check: false
660
661
config-center:
662
address: zookeeper://127.0.0.1:2181
663
group: dubbo
664
665
metrics:
666
enabled: true
667
protocol: prometheus
668
port: 9090
669
```
670
671
### Spring Boot Actuator Integration
672
673
Integration with Spring Boot Actuator for monitoring and management.
674
675
```java { .api }
676
/**
677
* Dubbo actuator auto-configuration
678
*/
679
@Configuration
680
@ConditionalOnClass({Endpoint.class, DubboBootstrap.class})
681
@ConditionalOnProperty(prefix = "management.endpoint.dubbo", name = "enabled", matchIfMissing = true)
682
public class DubboActuatorAutoConfiguration {
683
684
@Bean
685
@ConditionalOnMissingBean
686
public DubboEndpoint dubboEndpoint() {
687
return new DubboEndpoint();
688
}
689
690
@Bean
691
@ConditionalOnMissingBean
692
public DubboHealthIndicator dubboHealthIndicator() {
693
return new DubboHealthIndicator();
694
}
695
696
@Bean
697
@ConditionalOnMissingBean
698
public DubboMetadataEndpoint dubboMetadataEndpoint() {
699
return new DubboMetadataEndpoint();
700
}
701
}
702
703
/**
704
* Dubbo endpoint for actuator
705
*/
706
@Component
707
@Endpoint(id = "dubbo")
708
public class DubboEndpoint {
709
@ReadOperation
710
public Map<String, Object> dubbo() {
711
Map<String, Object> result = new HashMap<>();
712
result.put("application", getDubboApplication());
713
result.put("protocols", getDubboProtocols());
714
result.put("registries", getDubboRegistries());
715
result.put("services", getDubboServices());
716
result.put("references", getDubboReferences());
717
return result;
718
}
719
720
@ReadOperation
721
public Map<String, Object> services() {
722
return getDubboServices();
723
}
724
725
@ReadOperation
726
public Map<String, Object> references() {
727
return getDubboReferences();
728
}
729
730
@ReadOperation
731
public Map<String, Object> configs() {
732
Map<String, Object> configs = new HashMap<>();
733
configs.put("application", getDubboApplication());
734
configs.put("protocols", getDubboProtocols());
735
configs.put("registries", getDubboRegistries());
736
return configs;
737
}
738
}
739
740
/**
741
* Dubbo health indicator
742
*/
743
@Component
744
public class DubboHealthIndicator implements HealthIndicator {
745
@Override
746
public Health health() {
747
DubboBootstrap bootstrap = DubboBootstrap.getInstance();
748
749
if (!bootstrap.isStarted()) {
750
return Health.down()
751
.withDetail("status", "Dubbo is not started")
752
.build();
753
}
754
755
756
return Health.up()
757
.withDetail("status", "Dubbo is running")
758
.withDetail("services", getExportedServicesCount())
759
.withDetail("references", getReferencedServicesCount())
760
.build();
761
}
762
}
763
```
764
765
**Actuator Endpoints:**
766
767
```properties
768
# Enable Dubbo actuator endpoints
769
management.endpoints.web.exposure.include=health,info,dubbo
770
management.endpoint.dubbo.enabled=true
771
management.endpoint.health.show-details=always
772
773
# Access endpoints:
774
# GET /actuator/dubbo - Overall Dubbo information
775
# GET /actuator/dubbo/services - Exported services
776
# GET /actuator/dubbo/references - Service references
777
# GET /actuator/dubbo/configs - Configuration details
778
# GET /actuator/health - Include Dubbo health status
779
```
780
781
### Spring Boot Test Support
782
783
Testing utilities for Dubbo Spring Boot applications.
784
785
```java { .api }
786
/**
787
* Dubbo test annotation for integration tests
788
*/
789
@Target(ElementType.TYPE)
790
@Retention(RetentionPolicy.RUNTIME)
791
@SpringBootTest
792
@ExtendWith(SpringExtension.class)
793
public @interface DubboTest {
794
/** Test application properties */
795
String[] properties() default {};
796
797
/** Test profiles */
798
String[] profiles() default {};
799
800
/** Enable embedded registry */
801
boolean embeddedRegistry() default true;
802
803
/** Registry port for testing */
804
int registryPort() default -1;
805
}
806
807
/**
808
* Mock Dubbo service annotation
809
*/
810
@Target({ElementType.FIELD, ElementType.METHOD})
811
@Retention(RetentionPolicy.RUNTIME)
812
public @interface MockDubboService {
813
/** Service interface */
814
Class<?> value();
815
816
/** Service version */
817
String version() default "";
818
819
/** Service group */
820
String group() default "";
821
}
822
```
823
824
**Testing Examples:**
825
826
```java
827
@DubboTest(
828
properties = {
829
"dubbo.application.name=test-app",
830
"dubbo.registry.address=N/A",
831
"dubbo.protocol.port=-1"
832
},
833
embeddedRegistry = false
834
)
835
class UserServiceTest {
836
837
@MockDubboService(UserService.class)
838
private UserService mockUserService;
839
840
@DubboReference
841
private UserService userService;
842
843
@Test
844
void testGetUser() {
845
// Mock service behavior
846
when(mockUserService.getUserById(1L))
847
.thenReturn(new User(1L, "Test User"));
848
849
// Test service call
850
User user = userService.getUserById(1L);
851
assertEquals("Test User", user.getName());
852
}
853
}
854
855
// Integration test with embedded registry
856
@DubboTest
857
@TestPropertySource(properties = {
858
"dubbo.application.name=integration-test",
859
"dubbo.registry.address=zookeeper://localhost:2181"
860
})
861
class DubboIntegrationTest {
862
863
@DubboReference
864
private GreeterService greeterService;
865
866
@Test
867
void testServiceIntegration() {
868
String result = greeterService.sayHello("Integration Test");
869
assertNotNull(result);
870
assertTrue(result.contains("Integration Test"));
871
}
872
}
873
```
874
875
### Lifecycle Management
876
877
Spring Boot application lifecycle integration with Dubbo.
878
879
```java { .api }
880
/**
881
* Dubbo lifecycle management
882
*/
883
@Component
884
public class DubboLifecycleComponentApplicationListener
885
implements ApplicationListener<ApplicationEvent> {
886
887
@Override
888
public void onApplicationEvent(ApplicationEvent event) {
889
if (event instanceof ContextRefreshedEvent) {
890
// Start Dubbo when Spring context is refreshed
891
onContextRefreshedEvent((ContextRefreshedEvent) event);
892
} else if (event instanceof ContextClosedEvent) {
893
// Stop Dubbo when Spring context is closed
894
onContextClosedEvent((ContextClosedEvent) event);
895
}
896
}
897
898
private void onContextRefreshedEvent(ContextRefreshedEvent event) {
899
DubboBootstrap bootstrap = DubboBootstrap.getInstance();
900
if (!bootstrap.isStarted()) {
901
bootstrap.start();
902
}
903
}
904
905
private void onContextClosedEvent(ContextClosedEvent event) {
906
DubboBootstrap bootstrap = DubboBootstrap.getInstance();
907
if (bootstrap.isStarted()) {
908
bootstrap.stop();
909
}
910
}
911
}
912
913
/**
914
* Graceful shutdown configuration
915
*/
916
@Configuration
917
public class DubboShutdownConfiguration {
918
919
@Bean
920
public ApplicationListener<ContextClosedEvent> dubboShutdownHook() {
921
return event -> {
922
// Graceful shutdown with timeout
923
DubboBootstrap bootstrap = DubboBootstrap.getInstance();
924
if (bootstrap.isStarted()) {
925
bootstrap.await(); // Wait for ongoing requests
926
bootstrap.stop(); // Stop Dubbo
927
}
928
};
929
}
930
}
931
```
932
933
**Complete Spring Boot Application Example:**
934
935
```java
936
@SpringBootApplication
937
@EnableDubbo(scanBasePackages = "com.example")
938
public class DubboSpringBootApplication {
939
940
public static void main(String[] args) {
941
// Enable graceful shutdown
942
System.setProperty("dubbo.shutdown.hook", "true");
943
944
SpringApplication app = new SpringApplication(DubboSpringBootApplication.class);
945
app.setRegisterShutdownHook(true);
946
app.run(args);
947
}
948
949
// Optional: Custom configuration
950
@Bean
951
@Primary
952
public ApplicationConfig applicationConfig() {
953
ApplicationConfig config = new ApplicationConfig();
954
config.setName("spring-boot-dubbo-app");
955
config.setVersion("1.0.0");
956
config.setQosEnable(true);
957
return config;
958
}
959
}
960
961
// Service provider
962
@DubboService
963
@Component
964
public class UserServiceImpl implements UserService {
965
966
@Autowired
967
private UserRepository userRepository;
968
969
@Override
970
public User getUserById(Long id) {
971
return userRepository.findById(id).orElse(null);
972
}
973
}
974
975
// Service consumer
976
@RestController
977
public class UserController {
978
979
@DubboReference
980
private UserService userService;
981
982
@GetMapping("/api/users/{id}")
983
public ResponseEntity<User> getUser(@PathVariable Long id) {
984
User user = userService.getUserById(id);
985
return user != null ? ResponseEntity.ok(user) : ResponseEntity.notFound().build();
986
}
987
}
988
```