色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

簡(jiǎn)化本地Feign調(diào)用的方法

jf_ro2CN3Fa ? 來(lái)源:碼農(nóng)參上 ? 2023-06-20 10:01 ? 次閱讀

在平常的工作中,OpenFeign作為微服務(wù)間的調(diào)用組件使用的非常普遍,接口配合注解的調(diào)用方式突出一個(gè)簡(jiǎn)便,讓我們能無(wú)需關(guān)注內(nèi)部細(xì)節(jié)就能實(shí)現(xiàn)服務(wù)間的接口調(diào)用。

但是工作中用久了,發(fā)現(xiàn)Feign也有些使用起來(lái)麻煩的地方,下面先來(lái)看一個(gè)問(wèn)題,再看看我們?cè)诠ぷ髦惺侨绾谓鉀Q,以達(dá)到簡(jiǎn)化Feign使用的目的。

先看問(wèn)題

在一個(gè)項(xiàng)目開(kāi)發(fā)的過(guò)程中,我們通常會(huì)區(qū)分開(kāi)發(fā)環(huán)境、測(cè)試環(huán)境和生產(chǎn)環(huán)境,如果有的項(xiàng)目要求更高的話,可能還會(huì)有個(gè)預(yù)生產(chǎn)環(huán)境。

開(kāi)發(fā)環(huán)境作為和前端開(kāi)發(fā)聯(lián)調(diào)的環(huán)境,一般使用起來(lái)都比較隨意,而我們?cè)谶M(jìn)行本地開(kāi)發(fā)的時(shí)候,有時(shí)候也會(huì)將本地啟動(dòng)的微服務(wù)注冊(cè)到注冊(cè)中心nacos上,方便進(jìn)行調(diào)試。

這樣,注冊(cè)中心的一個(gè)微服務(wù)可能就會(huì)擁有多個(gè)服務(wù)實(shí)例,就像下面這樣:

7f82bc4c-0f0a-11ee-962d-dac502259ad0.png

眼尖的小伙伴肯定發(fā)現(xiàn)了,這兩個(gè)實(shí)例的ip地址有一點(diǎn)不同。

線上環(huán)境現(xiàn)在一般使用容器化部署,通常都是由流水線工具打成鏡像然后扔到docker中運(yùn)行,因此我們?nèi)タ匆幌路?wù)在docker容器內(nèi)的ip:

7f990bbe-0f0a-11ee-962d-dac502259ad0.png

可以看到,這就是注冊(cè)到nacos上的服務(wù)地址之一,而列表中192開(kāi)頭的另一個(gè)ip,則是我們本地啟動(dòng)的服務(wù)的局域網(wǎng)地址。看一下下面這張圖,就能對(duì)整個(gè)流程一目了然了。

7fb393c6-0f0a-11ee-962d-dac502259ad0.jpg

總結(jié)一下:

兩個(gè)service都是通過(guò)宿主機(jī)的ip和port,把自己的信息注冊(cè)到nacos上

線上環(huán)境的service注冊(cè)時(shí)使用docker內(nèi)部ip地址

本地的service注冊(cè)時(shí)使用本地局域網(wǎng)地址

那么這時(shí)候問(wèn)題就來(lái)了,當(dāng)我本地再啟動(dòng)一個(gè)serviceB,通過(guò)FeignClient來(lái)調(diào)用serviceA中的接口時(shí),因?yàn)镕eign本身的負(fù)載均衡,就可能把請(qǐng)求負(fù)載均衡到兩個(gè)不同的serviceA實(shí)例。

如果這個(gè)調(diào)用請(qǐng)求被負(fù)載均衡到本地serviceA的話,那么沒(méi)什么問(wèn)題,兩個(gè)服務(wù)都在同一個(gè)192.168網(wǎng)段內(nèi),可以正常訪問(wèn)。但是如果負(fù)載均衡請(qǐng)求到運(yùn)行在docker內(nèi)的serviceA的話,那么問(wèn)題來(lái)了,因?yàn)?a href="http://m.1cnz.cn/v/tag/1722/" target="_blank">網(wǎng)絡(luò)不通,所以會(huì)請(qǐng)求失敗:

7fd42a50-0f0a-11ee-962d-dac502259ad0.png

說(shuō)白了,就是本地的192.168和docker內(nèi)的虛擬網(wǎng)段172.17屬于純二層的兩個(gè)不同網(wǎng)段,不能互訪,所以無(wú)法直接調(diào)用。

那么,如果想在調(diào)試時(shí)把請(qǐng)求穩(wěn)定打到本地服務(wù)的話,有一個(gè)辦法,就是指定在FeignClient中添加url參數(shù),指定調(diào)用的地址:

@FeignClient(value="serviceA",url="http://127.0.0.1:8088/")
publicinterfaceClientA{
@GetMapping("/test/get")
Stringget();
}

但是這么一來(lái)也會(huì)帶來(lái)點(diǎn)問(wèn)題:

代碼上線時(shí)需要再把注解中的url刪掉,還要再次修改代碼,如果忘了的話會(huì)引起線上問(wèn)題

如果測(cè)試的FeignClient很多的話,每個(gè)都需要配置url,修改起來(lái)很麻煩

那么,有什么辦法進(jìn)行改進(jìn)呢?為了解決這個(gè)問(wèn)題,我們還是得從Feign的原理說(shuō)起。

Feign原理

簡(jiǎn)單來(lái)說(shuō),就是項(xiàng)目中加的@EnableFeignClients這個(gè)注解,實(shí)現(xiàn)時(shí)有一行很重要的代碼:

@Import(FeignClientsRegistrar.class)

這個(gè)類實(shí)現(xiàn)了ImportBeanDefinitionRegistrar接口,在這個(gè)接口的registerBeanDefinitions方法中,可以手動(dòng)創(chuàng)建BeanDefinition并注冊(cè),之后spring會(huì)根據(jù)BeanDefinition實(shí)例化生成bean,并放入容器中。

Feign就是通過(guò)這種方式,掃描添加了@FeignClient注解的接口,然后一步步生成代理對(duì)象,具體流程可以看一下下面這張圖:

7ff8fc4a-0f0a-11ee-962d-dac502259ad0.jpg

后續(xù)在請(qǐng)求時(shí),通過(guò)代理對(duì)象的FeignInvocationHandler進(jìn)行攔截,并根據(jù)對(duì)應(yīng)方法進(jìn)行處理器的分發(fā),完成后續(xù)的http請(qǐng)求操作。

ImportBeanDefinitionRegistrar

上面提到的ImportBeanDefinitionRegistrar,在整個(gè)創(chuàng)建FeignClient的代理過(guò)程中非常重要, 所以我們先寫(xiě)一個(gè)簡(jiǎn)單的例子看一下它的用法。先定義一個(gè)實(shí)體類:

@Data
@AllArgsConstructor
publicclassUser{
Longid;
Stringname;
}

通過(guò)BeanDefinitionBuilder,向這個(gè)實(shí)體類的構(gòu)造方法中傳入具體值,最后生成一個(gè)BeanDefinition:

publicclassMyBeanDefinitionRegistrar
implementsImportBeanDefinitionRegistrar{
@Override
publicvoidregisterBeanDefinitions(AnnotationMetadataimportingClassMetadata,
BeanDefinitionRegistryregistry){
BeanDefinitionBuilderbuilder
=BeanDefinitionBuilder.genericBeanDefinition(User.class);
builder.addConstructorArgValue(1L);
builder.addConstructorArgValue("Hydra");

AbstractBeanDefinitionbeanDefinition=builder.getBeanDefinition();
registry.registerBeanDefinition(User.class.getSimpleName(),beanDefinition);
}
}

registerBeanDefinitions方法的具體調(diào)用時(shí)間是在之后的ConfigurationClassPostProcessor執(zhí)行postProcessBeanDefinitionRegistry方法時(shí),而registerBeanDefinition方法則會(huì)將BeanDefinition放進(jìn)一個(gè)map中,后續(xù)根據(jù)它實(shí)例化bean。

在配置類上通過(guò)@Import將其引入:

@Configuration
@Import(MyBeanDefinitionRegistrar.class)
publicclassMyConfiguration{
}

注入這個(gè)User測(cè)試:

@Service
@RequiredArgsConstructor
publicclassUserService{
privatefinalUseruser;

publicvoidgetUser(){
System.out.println(user.toString());
}
}

結(jié)果打印,說(shuō)明我們通過(guò)自定義BeanDefinition的方式成功手動(dòng)創(chuàng)建了一個(gè)bean并放入了spring容器中:

User(id=1,name=Hydra)

好了,準(zhǔn)備工作鋪墊到這結(jié)束,下面開(kāi)始正式的改造工作。

改造

到這里先總結(jié)一下,我們糾結(jié)的點(diǎn)就是本地環(huán)境需要FeignClient中配置url,但線上環(huán)境不需要,并且我們又不想來(lái)回修改代碼。

除了像源碼中那樣生成動(dòng)態(tài)代理以及攔截方法,官方文檔中還給我們提供了一個(gè)手動(dòng)創(chuàng)建FeignClient的方法。

簡(jiǎn)單來(lái)說(shuō),就是我們可以像下面這樣,通過(guò)Feign的Builder API來(lái)手動(dòng)創(chuàng)建一個(gè)Feign客戶端。

80198afa-0f0a-11ee-962d-dac502259ad0.png

簡(jiǎn)單看一下,這個(gè)過(guò)程中還需要配置Client、Encoder、Decoder、Contract、RequestInterceptor等內(nèi)容。

Client:實(shí)際http請(qǐng)求的發(fā)起者,如果不涉及負(fù)載均衡可以使用簡(jiǎn)單的Client.Default,用到負(fù)載均衡則可以使用LoadBalancerFeignClient,前面也說(shuō)了,LoadBalancerFeignClient中的delegate其實(shí)使用的也是Client.Default

Encoder和Decoder:Feign的編解碼器,在spring項(xiàng)目中使用對(duì)應(yīng)的SpringEncoder和ResponseEntityDecoder,這個(gè)過(guò)程中我們借用GsonHttpMessageConverter作為消息轉(zhuǎn)換器來(lái)解析json

RequestInterceptor:Feign的攔截器,一般業(yè)務(wù)用途比較多,比如添加修改header信息等,這里用不到可以不配

Contract:字面意思是合約,它的作用是將我們傳入的接口進(jìn)行解析驗(yàn)證,看注解的使用是否符合規(guī)范,然后將關(guān)于http的元數(shù)據(jù)抽取成結(jié)果并返回。如果我們使用RequestMapping、PostMapping、GetMapping之類注解的話,那么對(duì)應(yīng)使用的是SpringMvcContract

其實(shí)這里剛需的就只有Contract這一個(gè),其他都是可選的配置項(xiàng)。我們寫(xiě)一個(gè)配置類,把這些需要的東西都注入進(jìn)去:

@Slf4j
@Configuration(proxyBeanMethods=false)
@EnableConfigurationProperties({LocalFeignProperties.class})
@Import({LocalFeignClientRegistrar.class})
@ConditionalOnProperty(value="feign.local.enable",havingValue="true")
publicclassFeignAutoConfiguration{
static{
log.info("feignlocalroutestarted");
}

@Bean
@Primary
publicContractcontract(){
returnnewSpringMvcContract();
}

@Bean(name="defaultClient")
publicClientdefaultClient(){
returnnewClient.Default(null,null);
}

@Bean(name="ribbonClient")
publicClientribbonClient(CachingSpringLoadBalancerFactorycachingFactory,
SpringClientFactoryclientFactory){
returnnewLoadBalancerFeignClient(defaultClient(),cachingFactory,
clientFactory);
}

@Bean
publicDecoderdecoder(){
HttpMessageConverterhttpMessageConverter=newGsonHttpMessageConverter();
ObjectFactorymessageConverters=()->newHttpMessageConverters(httpMessageConverter);
SpringDecoderspringDecoder=newSpringDecoder(messageConverters);
returnnewResponseEntityDecoder(springDecoder);
}

@Bean
publicEncoderencoder(){
HttpMessageConverterhttpMessageConverter=newGsonHttpMessageConverter();
ObjectFactorymessageConverters=()->newHttpMessageConverters(httpMessageConverter);
returnnewSpringEncoder(messageConverters);
}
}

在這個(gè)配置類上,還有三行注解,我們一點(diǎn)點(diǎn)解釋。

首先是引入的配置類LocalFeignProperties,里面有三個(gè)屬性,分別是是否開(kāi)啟本地路由的開(kāi)關(guān)、掃描FeignClient接口的包名,以及我們要做的本地路由映射關(guān)系,addressMapping中存的是服務(wù)名和對(duì)應(yīng)的url地址:

@Data
@Component
@ConfigurationProperties(prefix="feign.local")
publicclassLocalFeignProperties{
//是否開(kāi)啟本地路由
privateStringenable;

//掃描FeignClient的包名
privateStringbasePackage;

//路由地址映射
privateMapaddressMapping;
}

下面這行注解則表示只有當(dāng)配置文件中feign.local.enable這個(gè)屬性為true時(shí),才使當(dāng)前配置文件生效:

@ConditionalOnProperty(value="feign.local.enable",havingValue="true")

最后,就是我們重中之重的LocalFeignClientRegistrar了,我們還是按照官方通過(guò)ImportBeanDefinitionRegistrar接口構(gòu)建BeanDefinition然后注冊(cè)的思路來(lái)實(shí)現(xiàn)。

并且,F(xiàn)eignClientsRegistrar的源碼中已經(jīng)實(shí)現(xiàn)好了很多基礎(chǔ)的功能,比如掃掃描包、獲取FeignClient的name、contextId、url等等,所以需要改動(dòng)的地方非常少,可以放心的大抄特超它的代碼。

先創(chuàng)建LocalFeignClientRegistrar,并注入需要用到的ResourceLoader、BeanFactory、Environment。

@Slf4j
publicclassLocalFeignClientRegistrarimplements
ImportBeanDefinitionRegistrar,ResourceLoaderAware,
EnvironmentAware,BeanFactoryAware{

privateResourceLoaderresourceLoader;
privateBeanFactorybeanFactory;
privateEnvironmentenvironment;

@Override
publicvoidsetResourceLoader(ResourceLoaderresourceLoader){
this.resourceLoader=resourceLoader;
}

@Override
publicvoidsetBeanFactory(BeanFactorybeanFactory)throwsBeansException{
this.beanFactory=beanFactory;
}

@Override
publicvoidsetEnvironment(Environmentenvironment){
this.environment=environment;
}

//先省略具體功能代碼...
}

然后看一下創(chuàng)建BeanDefinition前的工作,這一部分主要完成了包的掃描和檢測(cè)@FeignClient注解是否被添加在接口上的測(cè)試。下面這段代碼基本上是照搬源碼,除了改動(dòng)一下掃描包的路徑,使用我們自己在配置文件中配置的包名。

@Override
publicvoidregisterBeanDefinitions(AnnotationMetadataimportingClassMetadata,BeanDefinitionRegistryregistry){
ClassPathScanningCandidateComponentProviderscanner=ComponentScanner.getScanner(environment);
scanner.setResourceLoader(resourceLoader);
AnnotationTypeFilterannotationTypeFilter=newAnnotationTypeFilter(FeignClient.class);
scanner.addIncludeFilter(annotationTypeFilter);

StringbasePackage=environment.getProperty("feign.local.basePackage");
log.info("begintoscan{}",basePackage);

SetcandidateComponents=scanner.findCandidateComponents(basePackage);

for(BeanDefinitioncandidateComponent:candidateComponents){
if(candidateComponentinstanceofAnnotatedBeanDefinition){
log.info(candidateComponent.getBeanClassName());

//verifyannotatedclassisaninterface
AnnotatedBeanDefinitionbeanDefinition=(AnnotatedBeanDefinition)candidateComponent;
AnnotationMetadataannotationMetadata=beanDefinition.getMetadata();
Assert.isTrue(annotationMetadata.isInterface(),
"@FeignClientcanonlybespecifiedonaninterface");

Mapattributes=annotationMetadata
.getAnnotationAttributes(FeignClient.class.getCanonicalName());

Stringname=FeignCommonUtil.getClientName(attributes);
registerFeignClient(registry,annotationMetadata,attributes);
}
}
}

接下來(lái)創(chuàng)建BeanDefinition并注冊(cè),F(xiàn)eign的源碼中是使用的FeignClientFactoryBean創(chuàng)建代理對(duì)象,這里我們就不需要了,直接替換成使用Feign.builder創(chuàng)建。

privatevoidregisterFeignClient(BeanDefinitionRegistryregistry,
AnnotationMetadataannotationMetadata,Mapattributes){
StringclassName=annotationMetadata.getClassName();
Classclazz=ClassUtils.resolveClassName(className,null);
ConfigurableBeanFactorybeanFactory=registryinstanceofConfigurableBeanFactory
?(ConfigurableBeanFactory)registry:null;
StringcontextId=FeignCommonUtil.getContextId(beanFactory,attributes,environment);
Stringname=FeignCommonUtil.getName(attributes,environment);

BeanDefinitionBuilderdefinition=BeanDefinitionBuilder
.genericBeanDefinition(clazz,()->{
Contractcontract=beanFactory.getBean(Contract.class);
ClientdefaultClient=(Client)beanFactory.getBean("defaultClient");
ClientribbonClient=(Client)beanFactory.getBean("ribbonClient");
Encoderencoder=beanFactory.getBean(Encoder.class);
Decoderdecoder=beanFactory.getBean(Decoder.class);

LocalFeignPropertiesproperties=beanFactory.getBean(LocalFeignProperties.class);
MapaddressMapping=properties.getAddressMapping();

Feign.Builderbuilder=Feign.builder()
.encoder(encoder)
.decoder(decoder)
.contract(contract);

StringserviceUrl=addressMapping.get(name);
StringoriginUrl=FeignCommonUtil.getUrl(beanFactory,attributes,environment);

Objecttarget;
if(StringUtils.hasText(serviceUrl)){
target=builder.client(defaultClient)
.target(clazz,serviceUrl);
}elseif(StringUtils.hasText(originUrl)){
target=builder.client(defaultClient)
.target(clazz,originUrl);
}else{
target=builder.client(ribbonClient)
.target(clazz,"http://"+name);
}

returntarget;
});

definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
definition.setLazyInit(true);
FeignCommonUtil.validate(attributes);

AbstractBeanDefinitionbeanDefinition=definition.getBeanDefinition();
beanDefinition.setAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE,className);

//hasadefault,won'tbenull
booleanprimary=(Boolean)attributes.get("primary");
beanDefinition.setPrimary(primary);

String[]qualifiers=FeignCommonUtil.getQualifiers(attributes);
if(ObjectUtils.isEmpty(qualifiers)){
qualifiers=newString[]{contextId+"FeignClient"};
}

BeanDefinitionHolderholder=newBeanDefinitionHolder(beanDefinition,className,
qualifiers);
BeanDefinitionReaderUtils.registerBeanDefinition(holder,registry);
}

在這個(gè)過(guò)程中主要做了這么幾件事:

通過(guò)beanFactory拿到了我們?cè)谇懊鎰?chuàng)建的Client、Encoder、Decoder、Contract,用來(lái)構(gòu)建Feign.Builder

通過(guò)注入配置類,通過(guò)addressMapping拿到配置文件中服務(wù)對(duì)應(yīng)的調(diào)用url

通過(guò)target方法替換要請(qǐng)求的url,如果配置文件中存在則優(yōu)先使用配置文件中url,否則使用@FeignClient注解中配置的url,如果都沒(méi)有則使用服務(wù)名通過(guò)LoadBalancerFeignClient訪問(wèn)

在resources/META-INF目錄下創(chuàng)建spring.factories文件,通過(guò)spi注冊(cè)我們的自動(dòng)配置類:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=
com.feign.local.config.FeignAutoConfiguration

最后,本地打包即可:

mvncleaninstall

測(cè)試

引入我們?cè)谏厦娲蚝玫陌捎诎幸呀?jīng)包含了spring-cloud-starter-openfeign,所以就不需要再額外引feign的包了:


com.cn.hydra
feign-local-enhancer
1.0-SNAPSHOT

在配置文件中添加配置信息,啟用組件:

feign:
local:
enable:true
basePackage:com.service
addressMapping:
hydra-service:http://127.0.0.1:8088
trunks-service:http://127.0.0.1:8099

創(chuàng)建一個(gè)FeignClient接口,注解的url中我們可以隨便寫(xiě)一個(gè)地址,可以用來(lái)測(cè)試之后是否會(huì)被配置文件中的服務(wù)地址覆蓋:

@FeignClient(value="hydra-service",
contextId="hydra-serviceA",
url="http://127.0.0.1:8099/")
publicinterfaceClientA{
@GetMapping("/test/get")
Stringget();

@GetMapping("/test/user")
UsergetUser();
}

啟動(dòng)服務(wù),過(guò)程中可以看見(jiàn)了執(zhí)行掃描包的操作:

803fe876-0f0a-11ee-962d-dac502259ad0.png

在替換url過(guò)程中添加一個(gè)斷點(diǎn),可以看到即使在注解中配置了url,也會(huì)優(yōu)先被配置文件中的服務(wù)url覆蓋:

806f7668-0f0a-11ee-962d-dac502259ad0.png

使用接口進(jìn)行測(cè)試,可以看到使用上面的代理對(duì)象進(jìn)行了訪問(wèn)并成功返回了結(jié)果:

809b35be-0f0a-11ee-962d-dac502259ad0.png

如果項(xiàng)目需要發(fā)布正式環(huán)境,只需要將配置feign.local.enable改為false或刪掉,并在項(xiàng)目中添加Feign原始的@EnableFeignClients即可。

總結(jié)

本文提供了一個(gè)在本地開(kāi)發(fā)過(guò)程中簡(jiǎn)化Feign調(diào)用的思路,相比之前需要麻煩的修改FeignClient中的url而言,能夠節(jié)省不少的無(wú)效勞動(dòng),并且通過(guò)這個(gè)過(guò)程,也可以幫助大家了解我們平常使用的這些組件是怎么與spring結(jié)合在一起的,熟悉spring的擴(kuò)展點(diǎn)。





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 編解碼器
    +關(guān)注

    關(guān)注

    0

    文章

    261

    瀏覽量

    24252
  • URL
    URL
    +關(guān)注

    關(guān)注

    0

    文章

    139

    瀏覽量

    15373
  • 虛擬機(jī)
    +關(guān)注

    關(guān)注

    1

    文章

    919

    瀏覽量

    28279
  • HTTP接口
    +關(guān)注

    關(guān)注

    0

    文章

    21

    瀏覽量

    1814

原文標(biāo)題:簡(jiǎn)化本地Feign調(diào)用,老手教你這么玩

文章出處:【微信號(hào):芋道源碼,微信公眾號(hào):芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    labview屬性節(jié)點(diǎn)、本地變量和直接數(shù)據(jù)流不同調(diào)用方法速度

    1、直接數(shù)據(jù)流,速度最快2、本地變量,速度稍慢3、采用屬性節(jié)點(diǎn)Description,速度慢了一個(gè)數(shù)量級(jí)4、直接數(shù)據(jù)流+屬性節(jié)點(diǎn)只增加為兩者單獨(dú)調(diào)用時(shí)間的累加。5、屬性節(jié)點(diǎn)Value為什么比屬性節(jié)點(diǎn)
    發(fā)表于 11-14 17:13

    如何簡(jiǎn)化程序框圖(方法)

    1.如何顯示子VI的部分控件于被調(diào)用該子VI的程序前面板上?2.程序框圖比較亂有哪些方法簡(jiǎn)化?比如如何簡(jiǎn)化程序框圖比較獨(dú)立的程序(自定義函數(shù)嗎?)
    發(fā)表于 04-05 14:17

    屬性節(jié)點(diǎn)、本地變量和直接數(shù)據(jù)流調(diào)用方法對(duì)速度的影響

    1、直接數(shù)據(jù)流,速度最快2、本地變量,速度稍慢3、采用屬性Description,速度慢了一個(gè)數(shù)量級(jí)4、直接數(shù)據(jù)流+屬性節(jié)點(diǎn)只增加為兩者單獨(dú)調(diào)用時(shí)間的累加。5、屬性節(jié)點(diǎn)Value為什么比屬性節(jié)點(diǎn)
    發(fā)表于 11-13 11:16

    matlab自定義函數(shù)調(diào)用方法

    matlab自定義函數(shù)調(diào)用方法 命令文件/函數(shù)文件+ 函數(shù)文件 - 多
    發(fā)表于 11-29 13:14 ?88次下載

    單片機(jī)系統(tǒng)中Web Service的調(diào)用方法研究

    本文介紹了一種在單片機(jī)系統(tǒng)中利用嵌入式網(wǎng)絡(luò)模塊實(shí)現(xiàn)Web Service調(diào)用方法,利用嵌入式網(wǎng)絡(luò)模塊實(shí)現(xiàn)串口到以太網(wǎng)數(shù)據(jù)的轉(zhuǎn)換,將串行數(shù)據(jù)封裝成Web Service請(qǐng)求包.它簡(jiǎn)化了下位機(jī)和
    發(fā)表于 09-10 15:55 ?18次下載

    vb調(diào)用excel方法大全

    電子發(fā)燒友網(wǎng)站提供《vb調(diào)用excel方法大全.docx》資料免費(fèi)下載
    發(fā)表于 04-14 10:27 ?6次下載

    Linux常見(jiàn)調(diào)用shell腳本的三種方法

    編寫(xiě)Linux下的應(yīng)用程序時(shí)有時(shí)需要調(diào)用Linux的相關(guān)shell腳本,在這些腳本中通過(guò)調(diào)用Linux的相關(guān)函數(shù)實(shí)現(xiàn)對(duì)應(yīng)的功能。比如使用ifconfig配置本地的IP地址,采用這種方式省去了自己編寫(xiě)應(yīng)用程序去實(shí)現(xiàn)的麻煩。
    的頭像 發(fā)表于 06-28 14:28 ?8447次閱讀

    Oracle調(diào)用外部動(dòng)態(tài)庫(kù)的設(shè)置方法

    Oracle調(diào)用外部動(dòng)態(tài)庫(kù)的設(shè)置方法(電源技術(shù)及應(yīng)用總結(jié))-該文檔為Oracle調(diào)用外部動(dòng)態(tài)庫(kù)的設(shè)置講解文檔,是一份不錯(cuò)的參考資料,感興趣的可以先下載看看,,,,,,,,,,,,,
    發(fā)表于 09-28 13:57 ?12次下載
    Oracle<b class='flag-5'>調(diào)用</b>外部動(dòng)態(tài)庫(kù)的設(shè)置<b class='flag-5'>方法</b>

    C調(diào)用matlab方法

    C調(diào)用matlab方法介紹
    發(fā)表于 07-31 10:55 ?0次下載

    feign調(diào)用常見(jiàn)問(wèn)題避坑指南!

    摘要:主要是總結(jié)了一下這段時(shí)間在使用 feign 的過(guò)程中的遇到的一些坑點(diǎn)。
    的頭像 發(fā)表于 12-23 15:13 ?2058次閱讀

    動(dòng)態(tài)Feign的“萬(wàn)能”接口調(diào)用

    對(duì)于fegin調(diào)用,我們一般的用法都是為每個(gè)微服務(wù)都創(chuàng)建對(duì)應(yīng)的feignclient接口,然后為每個(gè)微服務(wù)的controller接口,一一編寫(xiě)對(duì)應(yīng)的方法,去調(diào)用對(duì)應(yīng)微服務(wù)的接口。
    發(fā)表于 12-26 11:42 ?3836次閱讀

    Feign第一次調(diào)用為什么會(huì)很慢?

    首先要了解Feign是如何進(jìn)行遠(yuǎn)程調(diào)用的,這里面包括,注冊(cè)中心、負(fù)載均衡、FeignClient之間的關(guān)系,微服務(wù)通過(guò)不論是eureka、nacos也好注冊(cè)到服務(wù)端,Feign是靠Ribbon做負(fù)載
    的頭像 發(fā)表于 08-17 15:00 ?1582次閱讀
    <b class='flag-5'>Feign</b>第一次<b class='flag-5'>調(diào)用</b>為什么會(huì)很慢?

    super調(diào)用父類的構(gòu)造方法

    我們分析這句話“父類對(duì)象的引用”,那說(shuō)明我們使用的時(shí)候只能在子類中使用,既然是對(duì)象的引用,那么我們也可以用來(lái)調(diào)用成員屬性以及成員方法,當(dāng)然了,這里的 super 關(guān)鍵字還能夠調(diào)用父類的構(gòu)造方法
    的頭像 發(fā)表于 10-10 16:42 ?929次閱讀
    super<b class='flag-5'>調(diào)用</b>父類的構(gòu)造<b class='flag-5'>方法</b>

    什么是遠(yuǎn)程過(guò)程調(diào)用

    )。 什么是遠(yuǎn)程過(guò)程調(diào)用呢? 那么對(duì)于一個(gè)聊天系統(tǒng)有int send_information(int friend_id,string msg)這個(gè)方法,我們的一個(gè)處理邏輯是不是這樣: 調(diào)用bool
    的頭像 發(fā)表于 11-10 10:10 ?1095次閱讀
    什么是遠(yuǎn)程過(guò)程<b class='flag-5'>調(diào)用</b>

    Feign的超時(shí)時(shí)間如何設(shè)置呢?

    今天來(lái)聊一聊前段時(shí)間看到的一個(gè)面試題,也是在實(shí)際項(xiàng)目中需要考慮的一個(gè)問(wèn)題,Feign 的超時(shí)時(shí)間如何設(shè)置?
    的頭像 發(fā)表于 11-15 10:22 ?1252次閱讀
    <b class='flag-5'>Feign</b>的超時(shí)時(shí)間如何設(shè)置呢?
    主站蜘蛛池模板: 免费国产在线观看| 亚洲AV久久无码精品九号| 欧美性xxx18一20| 日本免费xxx| 亚洲国产夜色在线观看| 2021国产精品视频一区| 成人a毛片久久免费播放| 国产精品永久在线| 理论片在线观看片免费| 色吧电影院| 用快播看av的网站| 趁老师睡着吃她的奶水| 精品欧美一区二区三区四区| 欧美日韩一级黄色片| 亚洲精品久久久久AV无码林星阑| 99久久国产露脸精品国产麻豆| 国产乱子影视频上线免费观看| 免费人成在线观看视频不卡| 性夜夜春夜夜爽AA片A| 99九九精品国产高清自在线| 国产午夜免费不卡精品理论片| 嫩草影院永久在线一二三四| 亚洲国产高清福利视频| V8成品人视频| 久久99r66热这里有精品| 少妇内射视频播放舔大片| 最近中文字幕2019免费版日本| 国产精品96久久久久久AV网址| 蜜芽tv在线观看免费网站| 亚洲 欧美 日韩 国产 视频| free俄罗斯性xxxxhd派对| 精品国产露脸久久AV麻豆| 涩涩游戏盒| 99精品在线| 精品在线观看一区| 双性被疯狂灌满精NP| 999av视频| 久久99视热频国只有精品| 婷婷射精AV这里只有精品| av亚洲2017色天堂| 久久久大香菇|