独立应用feign能够帮助我们解决什么样的问题或者带来什么好处呢。一方面是优雅,优雅的代码总是具有更好的可读性,这将意味着可能具有更好的维护性。另一方面是独立,独立意味着它可以不依赖繁琐的框架,意味着能够在更多的环境中得到应用。
1、建立一个基于maven的普通的Java项目,pom.xml配置如下
io.github.openfeign feign-core 9.7.0 io.github.openfeign feign-gson 9.7.0
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 MapactionMap = new HashMap<>(); private static Map feignServiceMap = new HashMap<>(); public static T getAction(Class interClass){ return (T) actionMap.get(interClass); } public static T action(Class 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 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 getService(Class 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 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、运行结果