In the micro-service architecture, if the use of Springcloud, then only need to integrate springfeign, springfeign can be very friendly to help us with service requests, object resolution and so on.
However, Spingcloud is dependent on springboot. In the old spring project there is usually no integration springboot, so how do we use the feign component to make the call?
In this case, you can only use native feign, feign user's manual: https://www.cnblogs.com/chenkeyu/p/9017996.html
Two questions about using native feign:
First, the native feign can only parse one interface at a time, generate the corresponding request proxy object, if there is more than one call interface in a package will be a lot of trouble parsing.
Second, the call agent generated by feign is just an ordinary object, how to register in spring so that we can use @autowired to inject at any time.
Solution:
One, for many times the problem of resolution, you can specify the scan package path, and then the class in the package to resolve in turn. Use tool: Https://github.com/lukehutch/fast-classpath-scanner
Second, realize Beanfactorypostprocessor interface, extend spring container function.
Specific code: MAVEN dependency:
<Dependency> <groupId>Com.netflix.feign</groupId> <Artifactid>Feign-core</Artifactid> <version>8.18.0</version> </Dependency> <Dependency> <groupId>Com.netflix.feign</groupId> <Artifactid>Feign-jackson</Artifactid> <version>8.18.0</version> </Dependency> <Dependency> <groupId>Io.github.lukehutch</groupId> <Artifactid>Fast-classpath-scanner</Artifactid> <version>2.18.1</version> </Dependency>
Custom annotations: In the process of scanning an interface, a custom annotation can be used to differentiate the feign interface and specify the invoked service URL
Import Java.lang.annotation.ElementType;
Import java.lang.annotation.Retention;
Import Java.lang.annotation.RetentionPolicy;
Import Java.lang.annotation.Target;
@Target ({elementtype.type})
@Retention (Retentionpolicy.runtime)
Public @interface Feignapi {
/**
* Service address of the call
* @return
*/
String serviceurl ();
}
Generate the feign agent and register to the spring implementation class:
Importfeign. feign;Importfeign. Request;Importfeign. Retryer;ImportFeign.jackson.JacksonDecoder;ImportFeign.jackson.JacksonEncoder;ImportIo.github.lukehutch.fastclasspathscanner.FastClasspathScanner;ImportIo.github.lukehutch.fastclasspathscanner.scanner.ScanResult;ImportOrg.springframework.beans.factory.config.BeanFactoryPostProcessor;Importorg.springframework.beans.factory.config.ConfigurableListableBeanFactory;Importorg.springframework.stereotype.Component;Importjava.util.List; @Component Public classFeignclientregisterImplementsbeanfactorypostprocessor{//the scanned interface path PrivateString scanpath= "Com.xxx.api"; @Override Public voidpostprocessbeanfactory (configurablelistablebeanfactory beanfactory) {List<String> classes =Scan (Scanpath); if(classes==NULL){ return ; } System.out.println (classes); Feign.builder Builder=Getfeignbuilder (); if(Classes.size () >0){ for(String claz:classes) {Class<?> Targetclass =NULL; Try{Targetclass=Class.forName (Claz); String URL=targetclass.getannotation (Feignapi.class). Serviceurl (); if(Url.indexof ("http//")!=0) {URL= "http//" +URL; } Object Target=builder.target (targetclass, URL); Beanfactory.registersingleton (Targetclass.getname (), target); } Catch(Exception e) {Throw Newruntimeexception (E.getmessage ()); } } } } PublicFeign.builder Getfeignbuilder () {Feign.builder Builder=Feign.builder (). Encoder (NewJacksonencoder ()). Decoder (NewJacksondecoder ()). Options (NewRequest.options (1000, 3500). Retryer (NewRetryer.default (5000, 5000, 3)); returnBuilder; } PublicList<string>Scan (String path) {scanresult result=NewFastclasspathscanner (Path). Matchclasseswithannotation (Feignapi.class, (class<?> AClass){}). scan (); if(result!=NULL){ returnresult.getnamesofallinterfaceclasses (); } return NULL; }}
Write an example of the calling interface:
ImportCom.xiaokong.core.base.Result;ImportCom.xiaokong.domain.DO.DeptRoom;Importfeign. Headers;Importfeign. Param;Importfeign. Requestline;ImportCom.xiaokong.register.FeignApi;Importjava.util.List; @FeignApi (serviceurl= "http://localhost:8085") Public InterfaceRoomapi {@Headers ({"Content-type:application/json", "Accept:application/json"}) @RequestLine ("Get/room/selectbyid?id={id}") Result<DeptRoom> Selectbyid (@Param (value= "id") String ID); @Headers ({"Content-type:application/json", "Accept:application/json"}) @RequestLine ("Get/room/test") Result<List<DeptRoom>>selectlist ();}
Examples of interface use:
@Service Public class serviceimpl{ // The interface is injected directly into the bean to be used @Autowired Private Roomapi Roomapi; @Test publicvoid demo () { result<DeptRoom> result = Roomapi.selectbyid ("1"); SYSTEM.OUT.PRINTLN (result);} }
Precautions :
1. If the interface returns a complex nested object, then it is important to explicitly specify generics, because feign, when parsing complex objects, needs to get an interface through reflection to return the generic type inside the object to correctly use Jackson parsing.
If the specified type is ambiguous, Jackson converts the JSON object to a Linkedhashmap type.
2. If you are using spring and need to call someone else's interface via HTTP, you can use this tool to simplify the operation of calls and parsing.
Simplifies HTTP calls without using springboot how to integrate native feign into spring