springboot如何实现一个starter

发布时间 2023-08-14 14:24:59作者: 打工人小余

创建内部的配置、Bean

比如声明一个Feign的配置类,对调用失败进行二次处理、请求头处理等

package com.ych.config;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.ych.common.utils.dto.ApiResultBase;
import com.ych.common.utils.enums.ApiResultCode;
import com.ych.common.utils.exception.ApiException;
import feign.Logger;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import feign.Response;
import feign.codec.ErrorDecoder;
import org.apache.commons.io.IOUtils;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.nio.charset.Charset;

@Configuration
public class FeignConfig implements RequestInterceptor, ErrorDecoder {
    private final org.slf4j.Logger logger = LoggerFactory.getLogger(FeignConfig.class);
    /**
     * NONE:默认的,不显示任何日志
     * BASIC:仅记录请求方法、URL、响应状态码及执行时间
     * HEADERS:出了BASIC中定义的信息之外,还有请求和响应的头信息
     * FULL:除了HEADERS中定义的信息之外,还有请求和响应的正文及元素
     */
    @Bean
    public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }

    /*
     * 增加请求头
     */
    @Override
    public void apply(RequestTemplate requestTemplate) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            //添加token
            String authorization = request.getHeader(HttpHeaders.AUTHORIZATION);
            if(StrUtil.isNotBlank(authorization)){
                requestTemplate.header(HttpHeaders.AUTHORIZATION, authorization);
            }
        }
    }

    @Override
    public Exception decode(String methodKey, Response response) {
        try {
            int status = response.status();
            if (status == 503) {
                return new ApiException(ApiResultCode.FeignFail.getCode(), String.format("%s: 服务不存在", methodKey), status);
            }
            String result = IOUtils.toString(response.body().asReader(Charset.defaultCharset()));
            ApiResultBase apiResult = JSONUtil.toBean(result, ApiResultBase.class);
            if (apiResult != null) {
                return new ApiException(ApiResultCode.FeignFail.getCode(), String.format("%s: %s", methodKey, apiResult.getMessage()), status);
            } else {
                logger.warn("OpenFeign异常处理错误:解析响应体失败,MethodKey: %s", methodKey);
                return new ApiException(ApiResultCode.FeignFail.getCode(), "解析响应体失败", status);
            }
        } catch (IOException ex) {
            logger.warn("OpenFeign异常处理错误:%s", ex.getMessage());
            return new ApiException(ApiResultCode.FeignFail.getCode(), String.format("%s: %s", methodKey, ex.getMessage()), response.status());
        }
    }

}

 

创建一个自动配置类自动配置类加载

声明一个自动配置类,用于加载你想要自动装配的各种配置类和各种需要开启的注解

package com.ych.config;

import com.alibaba.cloud.nacos.NacosConfigProperties;
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@EnableDiscoveryClient
@Import({FeignConfig.class})
public class NacosAutoConfiguration {
    private final Logger logger = LoggerFactory.getLogger(NacosAutoConfiguration.class);

    public NacosAutoConfiguration(NacosConfigProperties nacosConfigProperties, NacosDiscoveryProperties discoveryProperties) {
        logger.info("nacos config配置加载完成:{}",nacosConfigProperties.toString());
        logger.info("nacos discovery配置加载完成:{}",discoveryProperties.toString());
    }
}

 

添加默认加载的配置

在路径 resources\META-INF 下新建文件 spring.factories
内容如下

# 配置你自动配置类的完全限定类名即可
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.ych.config.NacosAutoConfiguration