<p><span style="color:#ff0000"><strong>本文采用的springcloud 版本 Dalston.SR4 所有例子以Dalston.SR4 版本为准</strong></span></p>
坑5、 无法扫描到引入包的服务降级实现,大多数情况 我们要对feignClient接口 显式声明一个fallback 以便进行服务降级 但是如果你的feignclient 接口 不在 springboot 的启动类的子类 会无法启动 显示
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean
with name 'com.xxx.feign.api.UserService':
FactoryBean threw exception on object creation;
nested exception is java.lang.IllegalStateException:
No fallback instance of type class com.xxx.feign.api.UserServiceHystrix found for feign client MEMBER-SERVICE
也就是你feign 接口的实现类 无法被注入
先看一下 源码:
/*
* Copyright 2013-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.feign;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
/**
-
Annotation for interfaces declaring that a REST client with that interface should be
-
created (e.g. for autowiring into another component). If ribbon is available it will be
-
used to load balance the backend requests, and the load balancer can be configured
-
using a <code>@RibbonClient</code> with the same name (i.e. value) as the feign client.
-
@author Spencer Gibb
-
@author Venil Noronha
*/
(ElementType.TYPE)
(RetentionPolicy.RUNTIME)
public FeignClient {/**
- The name of the service with optional protocol prefix. Synonym for {@link #name()
- name}. A name must be specified for all clients, whether or not a url is provided.
- Can be specified as property key, eg: ${propertyKey}.
*/
(“name”)
String value() default “”;
/**
- The service id with optional protocol prefix. Synonym for {@link #value() value}.
- @deprecated use {@link #name() name} instead
*/
String serviceId() default “”;
/**
- The service id with optional protocol prefix. Synonym for {@link #value() value}.
*/
(“value”)
String name() default “”;
/**
- Sets the <code>@Qualifier</code> value for the feign client.
*/
String qualifier() default “”;
/**
- An absolute URL or resolvable hostname (the protocol is optional).
*/
String url() default “”;
/**
- Whether 404s should be decoded instead of throwing FeignExceptions
*/
boolean decode404() default false;
/**
- A custom <code>@Configuration</code> for the feign client. Can contain override
- <code>@Bean</code> definition for the pieces that make up the client, for instance
- {@link feign.codec.Decoder}, {@link feign.codec.Encoder}, {@link feign.Contract}.
- @see FeignClientsConfiguration for the defaults
*/
Class<?>[] configuration() default {};
/**
- Fallback class for the specified Feign client interface. The fallback class must
- implement the interface annotated by this annotation and be a valid spring bean.
*/
Class<?> fallback() default void.class;
/**
- Define a fallback factory for the specified Feign client interface. The fallback
- factory must produce instances of fallback classes that implement the interface
- annotated by {@link FeignClient}. The fallback factory must be a valid spring
- bean.
- @see feign.hystrix.FallbackFactory for details.
*/
Class<?> fallbackFactory() default void.class;
/**
- Path prefix to be used by all method-level mappings. Can be used with or without
- <code>@RibbonClient</code>.
*/
String path() default “”;
/**
- Whether to mark the feign proxy as a primary bean. Defaults to true.
*/
boolean primary() default true;
}
* Fallback class for the specified Feign client interface. The fallback class must
implement the interface annotated by this annotation and be a valid spring bean. *
fallback 上会有这样的注释 说的是 声明feign客户端接口 的降级类 而且 这个降级类必须实现 该feign 接口 并且必须是一个可用的spring bean
如果你仅仅在这个实现类上加入spring bean 声明注解 比如 @Component 你会发现依然 无法注入 来大致猜想一下流程 熟悉springboot 的 应该清楚 springboot 启动的时候 会扫描其main类 所在包的子包进行 bean 实例化 如果不在子包 默认是扫描不到的 那么如何扫描到呢 声明扫描的路径 也就是需要在main类上使用注解@ComponentScan 注解 但是 如果 我们仅仅声明了 feign 降级实现的路径 你会发现 main类的子包无法扫描到了 所以 此处应该
@ComponentScan(basePackages = {"main 所在的包","降级类所在的包"})
配置好后 我们写一个降级类:
@Component
public class UserServiceHystrix implements UserService {
@Override
public User get(User user) {
System.out.println("<><><><><><><><><><> MEMBER-SERVICE 挂了<><><><><><><><><><> ");
user.setAge(20017);
user.setGender("male");
user.setName("服务挂了");
return user;
}
}
然后我们测试一下 启动消费方 不启动 提供方MEMBER-SERVICE 发现熔断可用:



spring cloud Dalston.SR4 feign 实际开发中踩坑(一)
https://my.oschina.net/u/2948566/blog/1591028
坑4、 无法扫描到引用包的feign接口
在实际的生产中 我们服务模块是有很多的, 如果 A的接口 B要调用 我们声明一次feigin客户端 api 然后C也要调A的接口 我们还要声明一次feigin客户端api 如果还有更多 就会有很多重复代码 为了提高代码复用,我们往往单独声明一个包来引入feigin 的api 其他包如果调用的化引入到工程中就行了 但是 问题来了 引用包无法被直接扫描到 我们知道 一个微服务模块 如果需要开启feign调用功能 需要加上
@EnableFeignClients
源码:
/*
* Copyright 2013-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.feign;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;
/**
-
Scans for interfaces that declare they are feign clients (via {@link FeignClient
-
<code>@FeignClient</code>}). Configures component scanning directives for use with
-
{@link org.springframework.context.annotation.Configuration
-
<code>@Configuration</code>} classes.
-
@author Spencer Gibb
-
@author Dave Syer
-
@since 1.0
*/
(RetentionPolicy.RUNTIME)
(ElementType.TYPE)
(FeignClientsRegistrar.class)
public @interface EnableFeignClients {/**
- Alias for the {@link #basePackages()} attribute. Allows for more concise annotation
- declarations e.g.: {@code @ComponentScan(“org.my.pkg”)} instead of
- {@code @ComponentScan(basePackages=“org.my.pkg”)}.
- @return the array of ‘basePackages’.
*/
String[] value() default {};
/**
- Base packages to scan for annotated components.
- <p>
- {@link #value()} is an alias for (and mutually exclusive with) this attribute.
- <p>
- Use {@link #basePackageClasses()} for a type-safe alternative to String-based
- package names.
- @return the array of ‘basePackages’.
*/
String[] basePackages() default {};
/**
- Type-safe alternative to {@link #basePackages()} for specifying the packages to
- scan for annotated components. The package of each class specified will be scanned.
- <p>
- Consider creating a special no-op marker class or interface in each package that
- serves no purpose other than being referenced by this attribute.
- @return the array of ‘basePackageClasses’.
*/
Class<?>[] basePackageClasses() default {};
/**
- A custom <code>@Configuration</code> for all feign clients. Can contain override
- <code>@Bean</code> definition for the pieces that make up the client, for instance
- {@link feign.codec.Decoder}, {@link feign.codec.Encoder}, {@link feign.Contract}.
- @see FeignClientsConfiguration for the defaults
*/
Class<?>[] defaultConfiguration() default {};
/**
- List of classes annotated with @FeignClient. If not empty, disables classpath scanning.
- @return
*/
Class<?>[] clients() default {};
}
其
中basePackages 声明 扫描 feignclie
nt 注解所在的包的包路径 声明后就能扫描到你在该包下@FeignClient 标记的 feign接口
探讨Spring Cloud Feign在微服务架构中的服务降级实现与接口扫描问题,包括降级类的正确配置及跨包引用的解决方案。

6064

被折叠的 条评论
为什么被折叠?



