Java中feign的独立使用

本文介绍了Feign框架如何通过优雅的注解和自动扫描机制简化Java应用中的远程服务调用。它强调了Feign的独立性和在不同环境中的适用性,以及如何通过Maven配置和使用@FeignService, @Url, @Wired注解来管理接口和服务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

独立应用feign能够帮助我们解决什么样的问题或者带来什么好处呢。一方面是优雅,优雅的代码总是具有更好的可读性,这将意味着可能具有更好的维护性。另一方面是独立,独立意味着它可以不依赖繁琐的框架,意味着能够在更多的环境中得到应用。

1、建立一个基于maven的普通的Java项目,pom.xml配置如下

<dependencies>
    <dependency>
        <groupId>io.github.openfeign</groupId>
        <artifactId>feign-core</artifactId>
        <version>9.7.0</version>
    </dependency>
    <dependency>
        <groupId>io.github.openfeign</groupId>
        <artifactId>feign-gson</artifactId>
        <version>9.7.0</version>
    </dependency>
</dependencies>

2、使用到的一些注解

FeignService.java
package com.suntown.annotation;

import java.lang.annotation.*;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FeignService{

}

  Url.java

package com.suntown.annotation;

import java.lang.annotation.*;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Url{
    public String value();
}

  Wired.java

  

package com.suntown.annotation;

import java.lang.annotation.*;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Wired{

}

3自动扫描package并管理feign接口类

FeignJust.java

package com.suntown;

import com.suntown.annotation.FeignService;
import com.suntown.annotation.Url;
import com.suntown.annotation.Wired;
import feign.Feign;
import feign.Request;
import feign.Retryer;
import feign.gson.GsonDecoder;
import feign.gson.GsonEncoder;
import sun.net.www.protocol.file.FileURLConnection;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.JarURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class FeignJust{
    private static Map<Class,Object> actionMap = new HashMap<>();
    private static Map<Class,Object> feignServiceMap = new HashMap<>();

    public static <T> T getAction(Class<T> interClass){
        return (T) actionMap.get(interClass);
    }

    public static <T> T action(Class<T> tClass,String url){
        T action = Feign.builder()
                .encoder(new GsonEncoder())
                .decoder(new GsonDecoder())
                .options(new Request.Options(1000, 3500))
                .retryer(new Retryer.Default(5000, 5000, 3))
                .target(
                        tClass,
                        url
                );
        return action;
    }

    public static String firstLower(String s){
        return (char)(s.charAt(0) + 32) + s.substring(1);
    }

    public static void scanPackage(String packageName) {
        try {
            String packageNamePath = packageName.replace(".","\\");
            URL url = FeignJust.class.getResource("FeignJust.class");
            URLConnection urlConnection = url.openConnection();
            if(urlConnection instanceof FileURLConnection){
                FileURLConnection fileURLConnection = (FileURLConnection)urlConnection;
                File rootFile = new File(FeignJust.class.getResource("/").toURI().getPath());

                File dirFile = new File(rootFile.getAbsolutePath() + File.separator + packageNamePath);
                File[] classesFile = dirFile.listFiles(new FilenameFilter() {
                    @Override
                    public boolean accept(File file, String s) {
                        return s.endsWith(".class");
                    }
                });
                for(File classFile : classesFile){
                    String classFilePath = classFile.getAbsolutePath();
                    String className = classFilePath.substring(rootFile.getAbsolutePath().length() + 1)
                            .replace("\\",".");
                    className = className.substring(0,className.length() - 6);

                    Class interClass = FeignJust.class.getClassLoader().loadClass(className);
                    Url urlAno = (Url)interClass.getAnnotation(Url.class);
                    if(urlAno!=null){
                        Object action = FeignJust.action(interClass,urlAno.value());
                        String classSimpleName = firstLower(interClass.getSimpleName());

                        actionMap.put(interClass,action);
                    }
                }
            }else if(urlConnection instanceof JarURLConnection){
                JarURLConnection jarURLConnection = (JarURLConnection)urlConnection;
                URL jarFileURL = jarURLConnection.getJarFileURL();
                File fileJarFile = new File(jarFileURL.toURI().getPath());
                JarFile jarFile = jarURLConnection.getJarFile();
                Enumeration<JarEntry> it = jarFile.entries();
                while(it.hasMoreElements()){
                    String className = it.nextElement().getName().replace("/",".");
                    if(className.endsWith(".class") && className.startsWith(packageName + ".")){
                        className = className.substring(0,className.length() - 6);
                        Class interClass = FeignJust.class.getClassLoader().loadClass(className);
                        Url urlAno = (Url)interClass.getAnnotation(Url.class);
                        if(urlAno!=null){
                            Object action = FeignJust.action(interClass,urlAno.value());
                            String classSimpleName = firstLower(interClass.getSimpleName());
                            actionMap.put(interClass,action);
                        }
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static <T> T getService(Class<T> interClass) {
        return (T) feignServiceMap.get(interClass);
    }

    public static void scanServicePackage(String packageName) {
        try {
            String packageNamePath = packageName.replace(".","\\");
            URL url = FeignJust.class.getResource("FeignJust.class");
            URLConnection urlConnection = url.openConnection();
            if(urlConnection instanceof FileURLConnection){
                FileURLConnection fileURLConnection = (FileURLConnection)urlConnection;
                File rootFile = new File(FeignJust.class.getResource("/").toURI().getPath());

                File dirFile = new File(rootFile.getAbsolutePath() + File.separator + packageNamePath);
                File[] classesFile = dirFile.listFiles(new FilenameFilter() {
                    @Override
                    public boolean accept(File file, String s) {
                        return s.endsWith(".class");
                    }
                });
                for(File classFile : classesFile){
                    String classFilePath = classFile.getAbsolutePath();
                    String className = classFilePath.substring(rootFile.getAbsolutePath().length() + 1)
                            .replace("\\",".");
                    className = className.substring(0,className.length() - 6);

                    Class interClass = FeignJust.class.getClassLoader().loadClass(className);
                    FeignService feignService = (FeignService)interClass.getAnnotation(FeignService.class);
                    if(feignService!=null){
                        Object serivce = FeignJust.serivce(interClass);
                        String classSimpleName = firstLower(interClass.getSimpleName());
                        if(serivce!=null){
                            Field[] fields = interClass.getDeclaredFields();
                            for(Field field : fields){
                                if(field.getAnnotation(Wired.class)!=null){
                                    field.setAccessible(true);
                                    Object action = getAction(field.getType());
                                    if(action!=null){
                                        field.set(serivce,action);
                                    }
                                }
                            }
                            feignServiceMap.put(interClass, serivce);
                        }
                    }
                }
            }else if(urlConnection instanceof JarURLConnection){
                JarURLConnection jarURLConnection = (JarURLConnection)urlConnection;
                URL jarFileURL = jarURLConnection.getJarFileURL();
                File fileJarFile = new File(jarFileURL.toURI().getPath());
                JarFile jarFile = jarURLConnection.getJarFile();
                Enumeration<JarEntry> it = jarFile.entries();
                while(it.hasMoreElements()){
                    String className = it.nextElement().getName().replace("/",".");
                    if(className.endsWith(".class") && className.startsWith(packageName + ".")){
                        className = className.substring(0,className.length() - 6);
                        Class interClass = FeignJust.class.getClassLoader().loadClass(className);
                        Url urlAno = (Url)interClass.getAnnotation(Url.class);
                        if(urlAno!=null){
                            Object action = FeignJust.action(interClass,urlAno.value());
                            String classSimpleName = firstLower(interClass.getSimpleName());
                            actionMap.put(interClass,action);
                        }
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    private static Object serivce(Class interClass) {
        try {
            return interClass.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }
}

4、测试接口类 IBaseAction.java

package com.suntown.interaction;

import com.suntown.annotation.Url;
import feign.Headers;
import feign.RequestLine;

@Url("http://localhost:8089")
public interface IBaseAction{
    @RequestLine("POST /login/login")
    @Headers({"Content-Type: application/json","Accept: application/json"})
    public Object login(Admin admin);

    public static class Admin{
        private String username;

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        private String password;
    }
}

5、feign接口的调用

package com.suntown;

import com.suntown.interaction.IBaseAction;

public class Main{
    public static void main(String[] args){
        FeignJust.scanPackage("com.suntown.interaction");
        IBaseAction baseAction = FeignJust.getAction(IBaseAction.class);
        IBaseAction.Admin admin = new IBaseAction.Admin();
        admin.setUsername("admin");
        admin.setPassword("123");
        Object result = baseAction.login(admin);
        System.out.println("class="+result.getClass()+","+result);
    }
}

6、运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天水麒麟姜伯约

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值