美文网首页
(二)Feign之注解Annotation自定义

(二)Feign之注解Annotation自定义

作者: 天草二十六_简村人 | 来源:发表于2019-08-21 15:11 被阅读0次

一、openfeign自带的注解,有以下三个,均实现接口org.springframework.cloud.openfeign.AnnotatedParameterProcessor。
1、RequestHeaderParameterProcessor
2、RequestParamParameterProcessor
3、PathVariableParameterProcessor
这里就不贴源码了。

二、自定义方法参数注解
1、实现接口AnnotatedParameterProcessor

import feign.MethodMetadata;
import org.springframework.cloud.openfeign.AnnotatedParameterProcessor;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import static feign.Util.emptyToNull;

public class FormParamParameterProcessor implements AnnotatedParameterProcessor {

    private static final Class<FormParam> ANNOTATION = FormParam.class;

    @Override
    public Class<? extends Annotation> getAnnotationType() {
        return ANNOTATION;
    }

    @Override
    public boolean processArgument(AnnotatedParameterContext context, Annotation annotation, Method method) {
        FormParam formParam = ANNOTATION.cast(annotation);
        String name = formParam.value();
        if (emptyToNull(name) != null) {
            context.setParameterName(name);

            MethodMetadata data = context.getMethodMetadata();
            data.formParams().add(name);
        }
        return true;
    }
}
import java.lang.annotation.*;

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FormParam {
    String value() default "";
}

2、注册

@Bean
public FormParamParameterProcessor formParamParameterProcessor(){
    return new FormParamParameterProcessor();
}

但是上述做法,会存在问题,具体原因见SpringMvcContract。

public SpringMvcContract(List<AnnotatedParameterProcessor> annotatedParameterProcessors, ConversionService conversionService) {
        this.processedMethods = new HashMap();
        this.resourceLoader = new DefaultResourceLoader();
        Assert.notNull(annotatedParameterProcessors, "Parameter processors can not be null.");
        Assert.notNull(conversionService, "ConversionService can not be null.");
        Object processors;
        if (!annotatedParameterProcessors.isEmpty()) {
            // 需要注意走这个分支,所以解决办法是手动追加默认注解和自定义注解。
            processors = new ArrayList(annotatedParameterProcessors);
        } else {
            // 遍历默认注解
            processors = this.getDefaultAnnotatedArgumentsProcessors();
        }

        this.annotatedArgumentProcessors = this.toAnnotatedArgumentProcessorMap((List)processors);
        this.conversionService = conversionService;
        this.expander = new SpringMvcContract.ConvertingExpander(conversionService);
    }

 private List<AnnotatedParameterProcessor> getDefaultAnnotatedArgumentsProcessors() {
        List<AnnotatedParameterProcessor> annotatedArgumentResolvers = new ArrayList();
        annotatedArgumentResolvers.add(new PathVariableParameterProcessor());
        annotatedArgumentResolvers.add(new RequestParamParameterProcessor());
        annotatedArgumentResolvers.add(new RequestHeaderParameterProcessor());
        return annotatedArgumentResolvers;
    }

3、解决办法:把自定义参数注解追加到列表里。

public SpringMvcContract(List<AnnotatedParameterProcessor> annotatedParameterProcessors) {
        this(annotatedParameterProcessors, new DefaultConversionService());
    }
    @Bean
    public Contract springMvcContract() {
        List<AnnotatedParameterProcessor> processors = new ArrayList<>();
        // 自定义注解
        processors.add(new FormParamParameterProcessor());

        //openfeign自带的三个注解
        processors.add(new PathVariableParameterProcessor());
        processors.add(new RequestHeaderParameterProcessor());
        processors.add(new RequestParamParameterProcessor());
        return new SpringMvcContract(processors);
    }

三、自定义参数注解的使用
注意方法中的自定义注解@FormParam("K")

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

//FeignServiceConfiguration见上一篇文章
@FeignClient(name = "user-service", url = "${user-service.url:}", configuration = FeignServiceConfiguration.class)
public interface UserApi {

    @RequestMapping(value = "/login", method = {RequestMethod.POST},
            consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE},
            produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
    LoginResponse login(@FormParam("K") String request);
}

相关文章

网友评论

      本文标题:(二)Feign之注解Annotation自定义

      本文链接:https://www.haomeiwen.com/subject/ctnbsctx.html