参考:https://www.jianshu.com/p/50fd582b739f
(1)在启动类添加@EnableFeignClients注解。其主要功能是初始化FeignClient的配置和动态执行client的请求。
(2)该注解的源码中@Import(FeignClientsRegistrar.class)是用来初始化FeignClient配置的
(3)FeignClientsRegistrar源码有个中药房方法,该方法有两个方法:
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata,
BeanDefinitionRegistry registry) {
registerDefaultConfiguration(metadata, registry);
registerFeignClients(metadata, registry);
}
注意:Feign默认集成了Hystrix容错器
Hystrix默认的超时时间是1秒,如果超过这个时间尚未响应,将会进入fallback代码。而首次请求往往会比较慢(因为Spring的懒加载机制,要实例化一些类),这个响应时间可能就大于1秒了。
.....待更新
FeignClientsConfiguration类中定义了Feign.Builder:
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ HystrixCommand.class, HystrixFeign.class })
protected static class HystrixFeignConfiguration {
@Bean
@Scope("prototype")
@ConditionalOnMissingBean
@ConditionalOnProperty(name = "feign.hystrix.enabled")
public Feign.Builder feignHystrixBuilder() {
return HystrixFeign.builder();
}
}
HystrixFeign.builder加载:
配置feign.hystrix.enabled=true
(1)使用Apache的Httpclient替换Ribbon/loadbalance配置:
理由:有时候,我们的Feignclient没有启用注册中心
配置:启用FeignClient的url属性来标明被调用方。此时,启用Httpclient的连接池方式可能会比Ribbon的客户端loadbalance方式更好。
参考:https://www.jianshu.com/p/50fd582b739f
2.1、注册FeignClient配置类和FeignClient BeanDefinition
在spring刷新容器时,当实例化我们的业务service时,如果发现注册了FeignClient,spring就会去实例化该FeignClient,同时会进行判断是否是代理bean,如果为代理bean,则调用 FeignClientFactoryBean
的 T getObject() throws Exception;
方法生成代理bean
2.2、实例化Feign上下文对象FeignContext
2.3、创建 Feign.builder 对象
2.4、生成负载均衡代理类
Feign调用方发起请求,发送至hystrix的HystrixInvocationHandler,通过服务名称,找到对应方法的methodHandler,methodHandler中封装了loadBalanceClient、retryer、RequestInterceptor等组件,如果引入了sleuth,这几个组件均是sleuth的包装类。然后通过以上组件构造 http
请求完成整个过程
2.5、生成默认代理类
2.6、注入到spring容器
具体源码分析参考:https://blog.csdn.net/forezp/article/details/83896098
什么是WebService参考:https://blog.csdn.net/RuiKe1400360107/article/details/83063644
@Configuration
@EnableWebMvc
public class WebServiceConfig extends WsConfigurerAdapter {
@Value("${webservice.url}")
private String baseUrl;
//医疗卫生人员
@Bean
public HospitalStaffService hospitalStaffService() {
return new HospitalStaffServiceImpl();
}
/**
* @Description: HospitalStaffService
*/
@Bean
public Endpoint endpoint1() {
EndpointImpl endpoint = new EndpointImpl(springBus(), hospitalStaffService());
endpoint.setPublishedEndpointUrl(
"http://" + baseUrl + "/registermanage/registermanage/hospitalStaffService");
endpoint.publish("/hospitalStaffService");
return endpoint;
}
}
@WebService注解参数说明:
/**
* 医疗卫生人员
*/
@WebService(serviceName = "HospitalStaffService", targetNamespace = "http://service.webService.registerManage.gl.ms.xx.com", endpointInterface = "com.xx.ms.gl.registerManage.webService.service.HospitalStaffService")
@Service
public class HospitalStaffServiceImpl implements HospitalStaffService {
@Autowired
BaseWebService baseWebService;
......略
/**
* 新增
*/
@Override
public String handleXMLInfo(String xml, String organCode) {
......略
// xml保存到业务表
Map xmlRes = baseWebService.handleXmlToEntity(xmlType, xml, organCode);
....
}
调用Fegin客户端
@Service
public class BaseServiceImpl implements BaseWebService {
@Autowired
private HandleXmlClient client;
....略
//新增xml
@Override
public Map handleXmlToEntity(String xmlType, String xml, String orgId) {
XmlHandleData xmlData = new XmlHandleData();
xmlData.setXml(xml);
xmlData.setXmlType(xmlType);
xmlData.setOrgId(orgId);
// 解析xml
return client.handleStrToEntity(xmlData);
}
注意:在使用fallback属性时,需要使用@Component注解保证fallback类被Spring容器扫描到
@Component
public class HandleXmlClientFallback implements HandleXmlClient{
@Override
public Map handleStrToEntity(XmlHandleData xmlData) {
Map res=new HashMap();
res.put("code", "-1");
res.put("message", "feign调用xml插入实体表方法失败");
return res;
}
}
Fegin是分布式架构服务之间,各子模块系统内部通信的核心。
下面是@FeignClient注解的参数说明:
注意:这里的Path路径也是需要调用的接口的全路径
@FeignClient(name = "healthfileshare", configuration = {
FeignClientsConfigurationCustom.class },fallback = HandleXmlClientFallback.class)
@Produces("application/json")
@Consumes("application/json")
public interface HandleXmlClient {
@POST
@Path(value = "/healthfileshare/subscribe/handleXml")
public Map handleStrToEntity(XmlHandleData xmlData);
}
@Path("/healthfileshare/subscribe")
@Api(tags = "healthfileshare")
public class SubscribeUI extends BaseContextAwareResource {
/**
* 接收xml保存到业务表
*
* @return
*/
@POST
@Path("/handleXml")
public Map handleStrToEntity(XmlHandleData xmlData) {
Map res = new HashMap();
Map map = new HashMap();
String result = "";
try {
map = xml2DbService.handleXml(xmlData.getXmlType(), xmlData.getXml(), xmlData.getOrgId());
} catch (Exception e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw, true));
result = sw.getBuffer().toString();
}
if (result.equals("") && map.get("code").equals("1")) {
// 成功
res.put("code", "0");
res.put("message", "xml保存到业务表成功");
} else {
res.put("code", "-1");
res.put("message", "xml保存到业务表失败," + result+","+map.get("message"));
}
return res;
}
}