問(wèn)題
No fallback instance of type ... found for feign client
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orderProcessorBiz':
Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: private com.xx.xx.service.IRemoteBridgeService com.xx.xx.biz.order.OrderProcessorBiz.remoteBridgeService;
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.xx.xx.service.IRemoteBridgeService':
FactoryBean threw exception on object creation; nested exception is java.lang.IllegalStateException:
No fallback instance of type class com.xx.xx.HystrixClientFallback found for feign client http://172.16.2.163:8001
Caused by: java.lang.IllegalStateException: No fallback instance of type class com.xx.xx.HystrixClientFallback found for feign client http://172.16.2.163:8001
通常需要確認(rèn)配置內(nèi)容
- 開(kāi)啟hystrix
feign.hystrix.enabled=true
- Fallback類(lèi)需要注解
@Component
依舊不行惶岭?
跟蹤代碼發(fā)現(xiàn) 是因?yàn)閷?duì)FeignClient 這個(gè)接口做了AOP切面邢疙。
@Pointcut("execution(* com.xx.xx.service.IR*.*(..))")
public void remoteCall() {
}
Trace日志看到這么一行:
[DEBUG] [17:50:22.410][JdkDynamicAopProxy][117]:Creating JDK dynamic proxy: target source is SingletonTargetSource for target object [com.xx.xx.service.HystrixClientFallback@32354b00]
然后考慮是不是因?yàn)镾pring AOP動(dòng)態(tài)代理默認(rèn)為 JDK動(dòng)態(tài)代理。
切面還是要切的奖恰,F(xiàn)allback也不能放棄恨统。因?yàn)檎{(diào)用的是接口,無(wú)論如何都要被切。
換成cglib后宪卿,問(wèn)題成功解決。
@EnableAspectJAutoProxy(proxyTargetClass = true)
這里給一個(gè)鏈接:
https://stackoverflow.com/questions/33110661/spring-aop-bean-injection-bug
原理
SpringAOP 的動(dòng)態(tài)代理有兩種實(shí)現(xiàn)赞季,JDK動(dòng)態(tài)代理愧捕,和Cglib。
Spring默認(rèn)使用 JDK動(dòng)態(tài)代理申钩。
當(dāng)類(lèi)至少實(shí)現(xiàn)了一個(gè)接口時(shí)次绘,使用JDK動(dòng)態(tài)代理。上文的Feign的Fallback類(lèi)正好是這樣撒遣。
至于究竟為什么cglib可以成功邮偎,就不去深究了,方案就兩個(gè)义黎,非此即彼禾进。
至于為什么 找不到 fallback instance?
private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
List<String> result = new ArrayList<String>();
// Check all bean definitions.
for (String beanName : this.beanDefinitionNames) {
// Only consider bean as eligible if the bean name
// is not defined as alias for some other bean.
if (!isAlias(beanName)) {
try {
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// Only check bean definition if it is complete.
if (!mbd.isAbstract() && (allowEagerInit ||
((mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading())) &&
!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
// In case of FactoryBean, match object created by FactoryBean.
boolean isFactoryBean = isFactoryBean(beanName, mbd);
boolean matchFound = (allowEagerInit || !isFactoryBean || containsSingleton(beanName)) &&
(includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type);
......
//以下代碼省略
問(wèn)題出現(xiàn)在isTypeMatch
這里isTypeMatch 返回了false廉涕,因?yàn)轵_不過(guò)JVM類(lèi)型檢查泻云。當(dāng)使用cglib則是匹配的艇拍。
全文完。
最近遇到的問(wèn)題宠纯,都特別詭異卸夕,但問(wèn)題終將被解決