千家信息网

Feign怎么自定义注解翻译器

发表于:2024-10-24 作者:千家信息网编辑
千家信息网最后更新 2024年10月24日,本篇内容主要讲解"Feign怎么自定义注解翻译器",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Feign怎么自定义注解翻译器"吧!Feign自定义注解翻译
千家信息网最后更新 2024年10月24日Feign怎么自定义注解翻译器

本篇内容主要讲解"Feign怎么自定义注解翻译器",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Feign怎么自定义注解翻译器"吧!

    Feign自定义注解翻译器

    新建自定义注解MyUrl

    package org.crazyit.cloud.contract; import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target; //这个注解只能定义方法@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface MyUrl {    //为注解配置两个属性    String url();    String method();}

    新建接口,使用MyUrl注解

    package org.crazyit.cloud.contract; public interface ContractClient {     @MyUrl(url = "/hello", method = "GET")    public String hello();}

    定义注解翻译器

    package org.crazyit.cloud.contract; import java.lang.annotation.Annotation;import java.lang.reflect.Method; import feign.Contract.BaseContract;import feign.MethodMetadata; public class MyContract extends BaseContract {     @Override    protected void processAnnotationOnClass(MethodMetadata data, Class clz) {        // 处理类级别注解     }     @Override    protected void processAnnotationOnMethod(MethodMetadata data,            Annotation annotation, Method method) {        // 注解是MyUrl类型的,才处理        if(MyUrl.class.isInstance(annotation)) {            MyUrl myUrl = method.getAnnotation(MyUrl.class);            String url = myUrl.url();            String httpMethod = myUrl.method();            data.template().method(httpMethod);            data.template().append(url);        }    }     @Override    protected boolean processAnnotationsOnParameter(MethodMetadata data,            Annotation[] annotations, int paramIndex) {        // 处理参数级别注解        return false;    } }

    测试类

    package org.crazyit.cloud.contract; import org.crazyit.cloud.jaxrs.RsClient; import feign.Feign;import feign.jaxrs.JAXRSContract; public class ContractMain {     public static void main(String[] args) {        ContractClient client = Feign.builder()                .contract(new MyContract())                .target(ContractClient.class,                "http://localhost:8080");        String result = client.hello();        System.out.println(result);    } }

    启动服务类

    测试

    Hello World

    Feign注解说明

    Feign是常用的微服务rpc调用框架,下面对一些注解说明

    @Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Inheritedpublic @interface FeignClient {    /**     * value和name的作用一样,如果没有配置url那么配置的值将作为服务名称,用于服务发现。反之只是一个名称。     *     */    @AliasFor("name")    String value() default "";    /**     * serviceId已经废弃了,直接使用name即可。     */    /** @deprecated */    @Deprecated    String serviceId() default "";    /**     *某个服务提供的接口不止定义在一个类中,这样启动时会报Bean的名称冲突。     * 解决方法:     * 1:参数配置添加     *  spring.main.allow-bean-definition-overriding=true     *     * 2:给每个client指定contextid     *     */    String contextId() default "";    /**     *     *  在注册Feign Client Configuration的时候需要一个名称,名称是通过getClientName方法获取的.     *  查看源码可知,如果配置了contextId就会用contextId,     *  如果没有配置就会去value,然后是name,最后是serviceId。     *  默认都没有配置,当出现一个服务有多个Feign Client的时候就会报错了。     *     *  其次的作用是在注册FeignClient中,contextId会作为Client 别名的一部分,如果配置了qualifier优先用qualifier作为别名。     *     */    /**     *见 value     *     */    @AliasFor("value")    String name() default "";    /**     *     * 在注册FeignClient中,指定client别名     *     */    String qualifier() default "";    /**     *     * url用于配置指定服务的地址,相当于直接请求这个服务,不经过Ribbon的服务选择。像调试等场景可以使用。     *     */    String url() default "";    /**     *     * 当调用请求发生404错误时,decode404的值为true,那么会执行decoder解码,否则抛出异常。     *     */    boolean decode404() default false;    /**     *     * configuration是配置Feign配置类,在配置类中可以自定义Feign的Encoder、Decoder、LogLevel、Contract等。     * 具体查看FeignConfiguration类     *     */    Class[] configuration() default {};    /**     *     * 定义容错的处理类,也就是回退逻辑,fallback的类必须实现Feign Client的接口,无法知道熔断的异常信息。     *     *     *     *     * 举例:     * //实现调用接口方法     * @Component     * public class UserRemoteClientFallback implements UserRemoteClient {     *        @Override     *        public User getUser(int id) {     *                return new User(0, "默认fallback");     *        }     * }     *     * //user服务     * @FeignClient(value = "user", fallback = UserRemoteClientFallback.class)     * public interface UserRemoteClient {     *        @GetMapping("/user/get")     *        public User getUser(@RequestParam("id")int id);     * }     *     *     */    Class fallback() default void.class;    /**     *     * 也是容错的处理,可以知道熔断的异常信息。熔断的另一种处理方法。     *     * //服务类作为参数传入FallbackFactory模板参数     * @Component     * public class UserRemoteClientFallbackFactory implements FallbackFactory {     *    private Logger logger = LoggerFactory.getLogger(UserRemoteClientFallbackFactory.class);     *     *    @Override     *    public UserRemoteClient create(Throwable cause) {     *            return new UserRemoteClient() {     *                    @Override     *                    public User getUser(int id) {     *                            logger.error("UserRemoteClient.getUser异常", cause);     *                            return new User(0, "默认");     *                    }     *            };     *    }     * }     *     */    Class fallbackFactory() default void.class;    /**     *     * path定义当前FeignClient访问接口时的统一前缀     * 比如接口地址是/user/get, 如果你定义了前缀是user, 那么具体方法上的路径就只需要写/get 即可。     *     * @FeignClient(name = "user", path="user")     * public interface UserRemoteClient {     *        @GetMapping("/get")     *        public User getUser(@RequestParam("id") int id);     * }     *     */    String path() default "";    /**     *  primary对应的是@Primary注解,默认为true.     *  官方这样设置也是有原因的。当我们的Feign实现了fallback后,也就意味着Feign Client有多个相同的Bean在Spring容器中,     *  当我们在使用@Autowired(建议使用@Resource注入对象)进行注入的时候,不知道注入哪个,所以我们需要设置一个优先级高的,@Primary注解就是干这件事情的。     *     *     */    boolean primary() default true;}

    到此,相信大家对"Feign怎么自定义注解翻译器"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

    0