我的编程空间,编程开发者的网络收藏夹
学习永远不晚

@RequestMapping和@FeginClient注解不能同时使用的问题

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

@RequestMapping和@FeginClient注解不能同时使用的问题

一、问题

在新版本SpringCloud中,增加了契约验证,当一个类上同时使用@RequestMapping 和 @FeignClient 注解时,会抛出此异常信息:java.lang.IllegalArgumentException: @RequestMapping annotation not allowed on @FeignClient interfaces

Caused by: java.lang.IllegalArgumentException: @RequestMapping annotation not allowed on @FeignClient interfaces    at org.springframework.cloud.openfeign.support.SpringMvcContract.processAnnotationOnClass(SpringMvcContract.java:180)    at feign.Contract$BaseContract.parseAndValidateMetadata(Contract.java:91)    at org.springframework.cloud.openfeign.support.SpringMvcContract.parseAndValidateMetadata(SpringMvcContract.java:187)    at feign.Contract$BaseContract.parseAndValidateMetadata(Contract.java:62)    at feign.ReflectiveFeign$ParseHandlersByName.apply(ReflectiveFeign.java:151)    at feign.ReflectiveFeign.newInstance(ReflectiveFeign.java:49)    at feign.Feign$Builder.target(Feign.java:269)    at org.springframework.cloud.openfeign.DefaultTargeter.target(DefaultTargeter.java:30)    at org.springframework.cloud.openfeign.FeignClientFactoryBean.loadBalance(FeignClientFactoryBean.java:373)    at org.springframework.cloud.openfeign.FeignClientFactoryBean.getTarget(FeignClientFactoryBean.java:421)    at org.springframework.cloud.openfeign.FeignClientFactoryBean.getObject(FeignClientFactoryBean.java:396)    at org.springframework.cloud.openfeign.FeignClientsRegistrar.lambda$registerFeignClient$0(FeignClientsRegistrar.java:235)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1249)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1191)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)    ... 28 common frames omitted

二、解决方案

方案一

将类上的@RequestMapping注解删掉,将路径更改到每个方法的路径上即可,然后使用@FeignClient自己的path属性指定路径

方案二

通过分析源码,替换源码相关约定,进行兼容处理

2.1 根据异常提示,定位错误提示位置:

1. 新版本实现:

// org.springframework.cloud.openfeign.support.SpringMvcContract#processAnnotationOnClass    @Override    protected void processAnnotationOnClass(MethodMetadata data, Class clz) {        RequestMapping classAnnotation = findMergedAnnotation(clz, RequestMapping.class);        if (classAnnotation != null) {            LOG.error("Cannot process class: " + clz.getName()                    + ". @RequestMapping annotation is not allowed on @FeignClient interfaces.");            throw new IllegalArgumentException("@RequestMapping annotation not allowed on @FeignClient interfaces");        }    }

2. 旧版本实现:

protected void processAnnotationOnClass(MethodMetadata data, Class clz) {        if (clz.getInterfaces().length == 0) {            RequestMapping classAnnotation = (RequestMapping)AnnotatedElementUtils.findMergedAnnotation(clz, RequestMapping.class);            if (classAnnotation != null && classAnnotation.value().length > 0) {                String pathValue = Util.emptyToNull(classAnnotation.value()[0]);                pathValue = this.resolve(pathValue);                if (!pathValue.startsWith("/")) {                    pathValue = "/" + pathValue;                }                data.template().insert(0, pathValue);            }        }    }

3. Contract契约接口:

在这里插入图片描述

4. processAnnotationOnClass接口方法实现:

在这里插入图片描述

public class SpringMvcContract extends Contract.BaseContract implements ResourceLoaderAware {

5. 解决方案:覆盖SpringMvcContract的processAnnotationOnClass接口方法实现

5.1 确定SpringMvcContract加载点

@ConditionalOnMissingBean 源码中的这个注解很关键,意思是我们可以替换Contract 的实现。所以目标很明确,就是要用自己的契约机制替换新版本中的契约

#org.springframework.cloud.openfeign.FeignClientsConfiguration#feignContract@Bean@ConditionalOnMissingBeanpublic Contract feignContract(ConversionService feignConversionService) {boolean decodeSlash = feignClientProperties == null || feignClientProperties.isDecodeSlash();return new SpringMvcContract(this.parameterProcessors, feignConversionService, decodeSlash);}
5.2 编写自己的SvcSpringContract契约

主要是更改processAnnotationOnClass方法的实现为老版本的实现方式(微调一下即可,具体看下面的代码)。

package xxxx.basic.config;import feign.*;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;import org.springframework.cloud.openfeign.AnnotatedParameterProcessor;import org.springframework.cloud.openfeign.CollectionFormat;import org.springframework.cloud.openfeign.FeignClient;import org.springframework.cloud.openfeign.annotation.*;import org.springframework.cloud.openfeign.encoding.HttpEncoding;import org.springframework.context.ConfigurableApplicationContext;import org.springframework.context.ResourceLoaderAware;import org.springframework.core.DefaultParameterNameDiscoverer;import org.springframework.core.MethodParameter;import org.springframework.core.ParameterNameDiscoverer;import org.springframework.core.ResolvableType;import org.springframework.core.annotation.AnnotatedElementUtils;import org.springframework.core.annotation.AnnotationUtils;import org.springframework.core.convert.ConversionService;import org.springframework.core.convert.TypeDescriptor;import org.springframework.core.convert.support.DefaultConversionService;import org.springframework.core.io.DefaultResourceLoader;import org.springframework.core.io.ResourceLoader;import org.springframework.http.InvalidMediaTypeException;import org.springframework.http.MediaType;import org.springframework.util.Assert;import org.springframework.util.StringUtils;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import java.lang.annotation.Annotation;import java.lang.reflect.Method;import java.lang.reflect.Parameter;import java.lang.reflect.Type;import java.util.*;import static feign.Util.checkState;import static feign.Util.emptyToNull;import static java.util.Optional.ofNullable;import static org.springframework.core.annotation.AnnotatedElementUtils.findMergedAnnotation;@ConditionalOnBeanpublic class SvcSpringContract extends Contract.BaseContract implements ResourceLoaderAware {    private static final Log LOG = LogFactory.getLog(SvcSpringContract.class);    private static final String ACCEPT = "Accept";    private static final String CONTENT_TYPE = "Content-Type";    private static final TypeDescriptor STRING_TYPE_DESCRIPTOR = TypeDescriptor.valueOf(String.class);    private static final TypeDescriptor ITERABLE_TYPE_DESCRIPTOR = TypeDescriptor.valueOf(Iterable.class);    private static final ParameterNameDiscoverer PARAMETER_NAME_DISCOVERER = new DefaultParameterNameDiscoverer();    private final Map, AnnotatedParameterProcessor> annotatedArgumentProcessors;    private final Map processedMethods = new HashMap<>();    private final ConversionService conversionService;    private final ConvertingExpanderFactory convertingExpanderFactory;    private ResourceLoader resourceLoader = new DefaultResourceLoader();    private boolean decodeSlash;    public SvcSpringContract() {        this(Collections.emptyList());    }    public SvcSpringContract(List annotatedParameterProcessors) {        this(annotatedParameterProcessors, new DefaultConversionService());    }    public SvcSpringContract(List annotatedParameterProcessors, ConversionService conversionService) {        this(annotatedParameterProcessors, conversionService, true);    }    public SvcSpringContract(List annotatedParameterProcessors, ConversionService conversionService, boolean decodeSlash) {        Assert.notNull(annotatedParameterProcessors, "Parameter processors can not be null.");        Assert.notNull(conversionService, "ConversionService can not be null.");        List processors = getDefaultAnnotatedArgumentsProcessors();        processors.addAll(annotatedParameterProcessors);        annotatedArgumentProcessors = toAnnotatedArgumentProcessorMap(processors);        this.conversionService = conversionService;        convertingExpanderFactory = new ConvertingExpanderFactory(conversionService);        this.decodeSlash = decodeSlash;    }    @Override    public void processAnnotationOnClass(MethodMetadata data, Class clz) {        if (data != null && clz.getInterfaces().length == 0) {            RequestMapping classAnnotation = AnnotatedElementUtils.findMergedAnnotation(clz, RequestMapping.class);            if (classAnnotation != null && classAnnotation.value().length > 0) {                String pathValue = Util.emptyToNull(classAnnotation.value()[0]);                pathValue = this.resolve(pathValue);                if (!pathValue.startsWith("/")) {                    pathValue = "/" + pathValue;                }                data.template().uri(pathValue);            }        }    }    @Override    public void setResourceLoader(ResourceLoader resourceLoader) {        this.resourceLoader = resourceLoader;    }    @Override    public MethodMetadata parseAndValidateMetadata(Class targetType, Method method) {        processedMethods.put(Feign.configKey(targetType, method), method);        return super.parseAndValidateMetadata(targetType, method);    }    @Override    public void processAnnotationOnMethod(MethodMetadata data, Annotation methodAnnotation, Method method) {        if (CollectionFormat.class.isInstance(methodAnnotation)) {            CollectionFormat collectionFormat = findMergedAnnotation(method, CollectionFormat.class);            data.template().collectionFormat(collectionFormat.value());        }        if (!RequestMapping.class.isInstance(methodAnnotation)                && !methodAnnotation.annotationType().isAnnotationPresent(RequestMapping.class)) {            return;        }        RequestMapping methodMapping = findMergedAnnotation(method, RequestMapping.class);        // HTTP Method        RequestMethod[] methods = methodMapping.method();        if (methods.length == 0) {            methods = new RequestMethod[]{RequestMethod.GET};        }        checkOne(method, methods, "method");        data.template().method(Request.HttpMethod.valueOf(methods[0].name()));        // path        checkAtMostOne(method, methodMapping.value(), "value");        if (methodMapping.value().length > 0) {            String pathValue = emptyToNull(methodMapping.value()[0]);            if (pathValue != null) {                pathValue = resolve(pathValue);                // Append path from @RequestMapping if value is present on method                if (!pathValue.startsWith("/") && !data.template().path().endsWith("/")) {                    pathValue = "/" + pathValue;                }                data.template().uri(pathValue, true);                if (data.template().decodeSlash() != decodeSlash) {                    data.template().decodeSlash(decodeSlash);                }            }        }        // produces        parseProduces(data, method, methodMapping);        // consumes        parseConsumes(data, method, methodMapping);        // headers        parseHeaders(data, method, methodMapping);        data.indexToExpander(new LinkedHashMap<>());    }    @Override    public boolean processAnnotationsOnParameter(MethodMetadata data, Annotation[] annotations, int paramIndex) {        boolean isHttpAnnotation = false;        AnnotatedParameterProcessor.AnnotatedParameterContext context = new SimpleAnnotatedParameterContext(data,                paramIndex);        Method method = processedMethods.get(data.configKey());        for (Annotation parameterAnnotation : annotations) {            AnnotatedParameterProcessor processor = annotatedArgumentProcessors                    .get(parameterAnnotation.annotationType());            if (processor != null) {                Annotation processParameterAnnotation;                // synthesize, handling @AliasFor, while falling back to parameter name on                // missing String #value():                processParameterAnnotation = synthesizeWithMethodParameterNameAsFallbackValue(parameterAnnotation,                        method, paramIndex);                isHttpAnnotation |= processor.processArgument(context, processParameterAnnotation, method);            }        }        if (!isMultipartFormData(data) && isHttpAnnotation && data.indexToExpander().get(paramIndex) == null) {            TypeDescriptor typeDescriptor = createTypeDescriptor(method, paramIndex);            if (conversionService.canConvert(typeDescriptor, STRING_TYPE_DESCRIPTOR)) {                Param.Expander expander = convertingExpanderFactory.getExpander(typeDescriptor);                if (expander != null) {                    data.indexToExpander().put(paramIndex, expander);                }            }        }        return isHttpAnnotation;    }    private String resolve(String value) {        if (StringUtils.hasText(value) && resourceLoader instanceof ConfigurableApplicationContext) {            return ((ConfigurableApplicationContext) resourceLoader).getEnvironment().resolvePlaceholders(value);        }        return value;    }    private void checkOne(Method method, Object[] values, String fieldName) {        checkState(values != null && values.length == 1, "Method %s can only contain 1 %s field. Found: %s",                method.getName(), fieldName, values == null ? null : Arrays.asList(values));    }    private void checkAtMostOne(Method method, Object[] values, String fieldName) {        checkState(values != null && (values.length == 0 || values.length == 1),                "Method %s can only contain at most 1 %s field. Found: %s", method.getName(), fieldName,                values == null ? null : Arrays.asList(values));    }    private void parseProduces(MethodMetadata md, Method method, RequestMapping annotation) {        String[] serverProduces = annotation.produces();        String clientAccepts = serverProduces.length == 0 ? null : emptyToNull(serverProduces[0]);        if (clientAccepts != null) {            md.template().header(ACCEPT, clientAccepts);        }    }    private void parseConsumes(MethodMetadata md, Method method, RequestMapping annotation) {        String[] serverConsumes = annotation.consumes();        String clientProduces = serverConsumes.length == 0 ? null : emptyToNull(serverConsumes[0]);        if (clientProduces != null) {            md.template().header(CONTENT_TYPE, clientProduces);        }    }    private void parseHeaders(MethodMetadata md, Method method, RequestMapping annotation) {        if (annotation.headers() != null && annotation.headers().length > 0) {            for (String header : annotation.headers()) {                int index = header.indexOf('=');                if (!header.contains("!=") && index >= 0) {                    md.template().header(resolve(header.substring(0, index)),resolve(header.substring(index + 1).trim()));                }            }        }    }    private Annotation synthesizeWithMethodParameterNameAsFallbackValue(Annotation parameterAnnotation, Method method,                int parameterIndex) {        Map annotationAttributes = AnnotationUtils.getAnnotationAttributes(parameterAnnotation);        Object defaultValue = AnnotationUtils.getDefaultValue(parameterAnnotation);        if (defaultValue instanceof String && defaultValue.equals(annotationAttributes.get(AnnotationUtils.VALUE))) {            Type[] parameterTypes = method.getGenericParameterTypes();            String[] parameterNames = PARAMETER_NAME_DISCOVERER.getParameterNames(method);            if (shouldAddParameterName(parameterIndex, parameterTypes, parameterNames)) {                annotationAttributes.put(AnnotationUtils.VALUE, parameterNames[parameterIndex]);            }        }        return AnnotationUtils.synthesizeAnnotation(annotationAttributes, parameterAnnotation.annotationType(), null);    }    private boolean shouldAddParameterName(int parameterIndex, Type[] parameterTypes, String[] parameterNames) {        // has a parameter name        return parameterNames != null && parameterNames.length > parameterIndex                // has a type                && parameterTypes != null && parameterTypes.length > parameterIndex;    }    private boolean isMultipartFormData(MethodMetadata data) {        Collection contentTypes = data.template().headers().get(HttpEncoding.CONTENT_TYPE);        if (contentTypes != null && !contentTypes.isEmpty()) {            String type = contentTypes.iterator().next();            try {                return Objects.equals(MediaType.valueOf(type), MediaType.MULTIPART_FORM_DATA);            } catch (InvalidMediaTypeException ignored) {                return false;            }        }        return false;    }    private List getDefaultAnnotatedArgumentsProcessors() {        List annotatedArgumentResolvers = new ArrayList<>();        annotatedArgumentResolvers.add(new MatrixVariableParameterProcessor());        annotatedArgumentResolvers.add(new PathVariableParameterProcessor());        annotatedArgumentResolvers.add(new RequestParamParameterProcessor());        annotatedArgumentResolvers.add(new RequestHeaderParameterProcessor());        annotatedArgumentResolvers.add(new QueryMapParameterProcessor());        annotatedArgumentResolvers.add(new RequestPartParameterProcessor());        return annotatedArgumentResolvers;    }    private Map, AnnotatedParameterProcessor> toAnnotatedArgumentProcessorMap(            List processors) {        Map, AnnotatedParameterProcessor> result = new HashMap<>();        for (AnnotatedParameterProcessor processor : processors) {            result.put(processor.getAnnotationType(), processor);        }        return result;    }    private static TypeDescriptor createTypeDescriptor(Method method, int paramIndex) {        Parameter parameter = method.getParameters()[paramIndex];        MethodParameter methodParameter = MethodParameter.forParameter(parameter);        TypeDescriptor typeDescriptor = new TypeDescriptor(methodParameter);        // Feign applies the Param.Expander to each element of an Iterable, so in those        // cases we need to provide a TypeDescriptor of the element.        if (typeDescriptor.isAssignableTo(ITERABLE_TYPE_DESCRIPTOR)) {            TypeDescriptor elementTypeDescriptor = getElementTypeDescriptor(typeDescriptor);            checkState(elementTypeDescriptor != null,                    "Could not resolve element type of Iterable type %s. Not declared?", typeDescriptor);            typeDescriptor = elementTypeDescriptor;        }        return typeDescriptor;    }    private static TypeDescriptor getElementTypeDescriptor(TypeDescriptor typeDescriptor) {        TypeDescriptor elementTypeDescriptor = typeDescriptor.getElementTypeDescriptor();        // that means it's not a collection but it is iterable, gh-135        if (elementTypeDescriptor == null && Iterable.class.isAssignableFrom(typeDescriptor.getType())) {            ResolvableType type = typeDescriptor.getResolvableType().as(Iterable.class).getGeneric(0);            if (type.resolve() == null) {                return null;            }            return new TypeDescriptor(type, null, typeDescriptor.getAnnotations());        }        return elementTypeDescriptor;    }    private static class ConvertingExpanderFactory {        private final ConversionService conversionService;        ConvertingExpanderFactory(ConversionService conversionService) {            this.conversionService = conversionService;        }        Param.Expander getExpander(TypeDescriptor typeDescriptor) {            return value -> {                Object converted = conversionService.convert(value, typeDescriptor, STRING_TYPE_DESCRIPTOR);                return (String) converted;            };        }    }    private class SimpleAnnotatedParameterContext implements AnnotatedParameterProcessor.AnnotatedParameterContext {        private final MethodMetadata methodMetadata;        private final int parameterIndex;        SimpleAnnotatedParameterContext(MethodMetadata methodMetadata, int parameterIndex) {            this.methodMetadata = methodMetadata;            this.parameterIndex = parameterIndex;        }        @Override        public MethodMetadata getMethodMetadata() {            return methodMetadata;        }        @Override        public int getParameterIndex() {            return parameterIndex;        }        @Override        public void setParameterName(String name) {            nameParam(methodMetadata, name, parameterIndex);        }        @Override        public Collection setTemplateParameter(String name, Collection rest) {            return addTemplateParameter(rest, name);        }        Collection addTemplateParameter(Collection possiblyNull, String paramName) {            Collection params = ofNullable(possiblyNull).map(ArrayList::new).orElse(new ArrayList<>());            params.add(String.format("{%s}", paramName));            return params;        }    }}
5.3 增加自动配置:
package xxxxx.basic.config;import feign.Contract;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;import org.springframework.cloud.openfeign.AnnotatedParameterProcessor;import org.springframework.cloud.openfeign.support.SpringMvcContract;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.annotation.Order;import org.springframework.core.convert.support.DefaultConversionService;import java.util.ArrayList;import java.util.List;@Configuration@ConditionalOnClass(SpringMvcContract.class)@Order(Integer.MIN_VALUE)public class SvcSpringContractConfig {    @Autowired(required = false)    private List parameterProcessors = new ArrayList<>();    @Bean    public Contract feignContract() {        return new SvcSpringContract(parameterProcessors, new DefaultConversionService(), true);    }}

来源地址:https://blog.csdn.net/qq_44734154/article/details/128624881

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

@RequestMapping和@FeginClient注解不能同时使用的问题

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

@RequestMapping和@FeginClient注解不能同时使用的问题

一、问题 在新版本SpringCloud中,增加了契约验证,当一个类上同时使用@RequestMapping 和 @FeignClient 注解时,会抛出此异常信息:java.lang.IllegalArgumentException: @
2023-08-16

解决SpringBoot中@RequestBody不能和Multipart同时传递的问题

问题描述 今天在做文件上传的时候,遇到了这么一个错误日志: Resolved[org.springframework.web.HttpMediaTypeNotSupportedException: Content type ‘multip
2023-08-16

SpringBoot中@RequestBody不能和Multipart同时传递的问题解决

本文主要介绍了SpringBoot中@RequestBody不能和Multipart同时传递的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-05-15

Android Studio和Gradle使用不同位置JDK的问题解决

初次安装Android Studio,遇到了不少问题,这是其中的一个,分享如下,同时求各位dalao关注一下啦((*^__^*) )使用不同的JDK位置可能会导致Gradle产生多个守护进程 ,首先Android Studio默认下使用的下
2022-06-06

同时使用swiper和echarts遇到的问题如何解决

今天小编给大家分享一下同时使用swiper和echarts遇到的问题如何解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。项
2023-07-06

C语言 volatile与const同时使用应注意的问题

“volatile”的含义是“请不要做没谱的优化,这个值可能变掉的”,而并非“你可以修改这个值”。因此,它们本来就不是矛盾的
2022-11-15

mybatis使用${}时sql注入的问题怎么解决

这篇文章给大家介绍mybatis使用${}时sql注入的问题怎么解决,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。mybatis使用${}时sql注入的问题最近在上线项目的时候,代码审查没有通过,提示有sql注入的风险
2023-06-22

关于同时使用swiper和echarts遇到的问题及解决方法

这篇文章主要介绍了关于同时使用swiper和echarts遇到的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
2023-05-15

Win2003系统中注册表被禁用不能使用问题解决方法

注册表在系统中是一个非常重要的存在,哪天你要是发现注册表不能使用了,你肯定非常的着急,因为注册表不能运行,便不能通过注册表编辑器来下达各种命令让系统来执行了。要是遇到这种情况要如何处理呢? 首先,按住win键+R键打开运行(win键是CTR
2023-06-05

SpringBoot对不同Bean注解的区别和使用场景说明

这篇文章主要介绍了SpringBoot对不同Bean注解的区别和使用场景说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-03-06

如何解决同一个wifi一个手机能用一个不能用的问题

这篇文章给大家分享的是有关如何解决同一个wifi一个手机能用一个不能用的问题的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。同一个wifi一个手机能用一个不能用的解决办法:首先打开手机设置,并在设置窗口点击选择无线
2023-06-06

Win7如何手动注册DLL文件以解决程序不能使用的问题

我们在使用Win7系统的时候,常常用到一些程序,会说需要重新注册一些程序相关的XXX.DLL文件,只有注册过后程序才能正常使用,那么我们该如何手动注册DLL文件呢?Win7手动注册DLL文件方法:在运行中输入regsvr32 c:\Wind
2023-06-11

如何解决智能ABC不能在VISTA下使用的问题

本篇内容主要讲解“如何解决智能ABC不能在VISTA下使用的问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何解决智能ABC不能在VISTA下使用的问题”吧!在安装了VISTA后,很多用户发
2023-06-14

关于Vite不能使用require问题的解决方法

在vue2中我们通常会在模板中通过三目运算符和require来实现动态图片,下面这篇文章主要给大家介绍了关于Vite不能使用require问题的解决方法,需要的朋友可以参考下
2022-11-13

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录