@mercyblitz Thanks for take a look at this. I'm a reader of your book
《SpringBoot编程思想》.
To be honest, your solutions is not easy to achieve.
Dubbo `@Service` Bean is not registered by child context created by Feign. The
child context sets its parent context to which `ApplicationContextAware` will
set to. We can do nothing to prevent the `ContextRefreshedEvent` received by
`ServiceBean`. Because the event is also published to parent context by
`AbstractApplicationContext`.
To see the event and source published by feign, it's easy to implement a
EventListener `ApplicationListener<ContextRefreshedEvent>`
```
@Component
public class FakeListener implements
ApplicationListener<ContextRefreshedEvent>, ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
ApplicationContext eventApplicationContext = event.getApplicationContext();
if
(applicationContext.getClass().equals(eventApplicationContext.getClass())) {
//Here is the right opportunity that Spring beans are ready.
}
....
}
```
If we print the `ContextRefreshedEvent`'s class name and its parent class name.
We will see like this:
```
//Published by Feign
:
org.springframework.context.annotation.AnnotationConfigApplicationContext@2cc3b0a7
FeignContext-XXXXXXXX
: ----- application-1
org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@2c1b9e4b
: ---------- bootstrap
org.springframework.context.annotation.AnnotationConfigApplicationContext@27adc16e
//Published by Spring when all Beans are ready
: application-1
org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@2c1b9e4b
: ----- bootstrap
org.springframework.context.annotation.AnnotationConfigApplicationContext@27adc16e
```
Whatever the `ApplicationContext` class is, the right one is setted by
`ApplicationContextAware` .
So the right way to fix this, is to let `ServiceBean` listen the Event
published by right context.
And there is a advantage for checking what `ApplicationContext` we really want,
to make it invoked only once.
My advice is to change the `ServiceBean` code:
```
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (!isExported() && !isUnexported()) {
if (logger.isInfoEnabled()) {
logger.info("The service ready on spring started. service: " +
getInterface());
}
ApplicationContext eventApplicationContext =
event.getApplicationContext();
if
(applicationContext.getClass().equals(eventApplicationContext.getClass())) {
export();//Here is the right opportunity that Spring beans are
ready.
}
}
}
```
**To those who meets this issue urgently**. When dubbo provider depends on a
FeignClient, we can use ApplicationContextAware, and get the client by
```
FeignClientInterface client =
applicationContext.getBean(FeignClientInterface.class);
```
[ Full content available at: https://github.com/apache/dubbo/issues/3990 ]
This message was relayed via gitbox.apache.org for
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]