当前位置: 首页 > news >正文

购物网站排名哪家好/seo搜索引擎优化方式

购物网站排名哪家好,seo搜索引擎优化方式,如何做房地产微信推送网站广告,dw做网站有雪花效果目录 一、继承体系 二、HandlerMapping 三、AbstractHandlerMapping 四、AbstractHandlerMethodMapping 4.1 成员属性 4.1.1 MappingRegistry内部类 4.2 AbstractHandlerMethodMapping的初始化 4.3 getHandlerInternal()方法:根据当前的请求url,…

目录

一、继承体系

二、HandlerMapping

三、AbstractHandlerMapping

四、AbstractHandlerMethodMapping

4.1 成员属性

4.1.1 MappingRegistry内部类

4.2 AbstractHandlerMethodMapping的初始化

4.3 getHandlerInternal()方法:根据当前的请求url,获取对应的处理器HandlerMathod

五、RequestMappingInfoHandlerMapping

5.1 成员属性和构造方法

5.2 该类复写了一些方法

5.2.1 getMappingPathPatterns

5.2.2 getMatchingMapping

5.2.3 getMappingComparator

5.2.4 handleMatch,handleNoMatch

六、RequestMappingHandlerMapping

6.1 成员属性

6.2 主要方法

6.2.1 覆写了afterPropertiesSet()

6.2.2 isHandler()

6.2.3 getMappingForMethod()


我们现在最流行的就是使用注解实现Controller,那这就会涉及到AbstractHandlerMethodMapping,这个类在我们分析处理请求的源码中非常重要,所以这里单独拿出来分析。

一、继承体系

二、HandlerMapping

HandlerMapping是处理器映射器的顶层接口,只声明了1个方法–>getHandler–>调用getHandler实际上返回的是一个HandlerExecutionChain,这是典型的command的模式(命令模式)的使用,这个HandlerExecutionChain不但持有Handler本身,还包括了处理这个HTTP请求相关的拦截器,方法原型如下:

HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;

三、AbstractHandlerMapping

实现HandlerMapping的抽象实现,模板方法模式,将一些共性的方法抽象成1个类。其实现了getHandler。如下:

public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {// 首先根据request获取handlerObject handler = getHandlerInternal(request);// 如果没有指定handler,就使用默认的if (handler == null) {handler = getDefaultHandler();}if (handler == null) {return null;}// Bean name or resolved handler?if (handler instanceof String) {String handlerName = (String) handler;handler = getApplicationContext().getBean(handlerName);}// 获取到了handler之后,再去获取拦截器,将两者封装到处理器执行链中返回return getHandlerExecutionChain(handler, request);
}

流程:

  1. 根据request获取对应的handler,该方法是1个抽象方法,由子类来实现,如下:

        

protected abstract Object getHandlerInternal(HttpServletRequest request) throws Exception;
  1. 如果没有对应的handler,就是要默认的handler
  2. 如果没有默认的handler,返回null
  3. 如果获取到的handler是一个字符串,说明这个是Bean名,则通过名称取出对应的 handler bean
  4. 把handler 封装到HandlerExecutionChain中并加上拦截器。如下:

        

		protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {// 1. 获得HandlerExecutionChainHandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));// 2. 根据请求获得对应的PathString lookupPath = this.urlPathHelper.getLookupPathForRequest(request);// 3. 遍历adaptedInterceptorsfor (HandlerInterceptor interceptor : this.adaptedInterceptors) {// 3.1 如果是MappedInterceptor,并且匹配当前的path,则加入到HandlerExecutionChain中if (interceptor instanceof MappedInterceptor) {MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {chain.addInterceptor(mappedInterceptor.getInterceptor());}}// 3.2 否则,直接加入到HandlerExecutionChainelse {chain.addInterceptor(interceptor);}}return chain;
}
  1. 获得HandlerExecutionChain
  2. 根据请求获得对应的Path
  3. 遍历adaptedInterceptors(拦截器)
    1. 如果是MappedInterceptor,并且匹配当前的path,则加入到HandlerExecutionChain中
    2. 否则,直接加入到HandlerExecutionChain

四、AbstractHandlerMethodMapping

AbstractHandlerMethodMapping是一个泛型类,其泛型参数T–>用来代表匹配handler的条件专门使用的一种类,这里的条件就不只是url了,还可以有很多其他条件,如request的类型,请求的参数,header等都可以作为匹配的HandlerMethod的条件。默认使用的是RequestMappingInfo,这个也是最常见的情况(只要是用注解实现Controller一般都是用RequestMappingInfo作为匹配条件类)。AbstractHandlerMethodMapping实现了InitializingBean接口。

4.1 成员属性

// scpoed 代理 bean的name的前缀。用来去除handler method的判断
private static final String SCOPED_TARGET_NAME_PREFIX = "scopedTarget.";// cors请求并且是options类型的请求并且请求头中含有Access-Control-Request-Method时返回的HandlerMethod
private static final HandlerMethod PREFLIGHT_AMBIGUOUS_MATCH =new HandlerMethod(new EmptyHandler(), ClassUtils.getMethod(EmptyHandler.class, "handle"));private static final CorsConfiguration ALLOW_CORS_CONFIG = new CorsConfiguration();static {ALLOW_CORS_CONFIG.addAllowedOrigin("*");ALLOW_CORS_CONFIG.addAllowedMethod("*");ALLOW_CORS_CONFIG.addAllowedHeader("*");ALLOW_CORS_CONFIG.setAllowCredentials(true);
}// 如果为true,则在当前applicationContext和祖先applicationContext中获取所有的bean,如果为false,则在当前上下文获得所有的bean
private boolean detectHandlerMethodsInAncestorContexts = false;// 向MappingRegistry中的nameLookup进行注册时用来生成beanName,这里默认使用的是RequestMappingInfoHandlerMethodMappingNamingStrategy
// 其规则为:类名里的大写字母组合+"#"+方法名.
private HandlerMethodMappingNamingStrategy<T> namingStrategy;// 用来存储各种映射关系
private final MappingRegistry mappingRegistry = new MappingRegistry();

4.1.1 MappingRegistry内部类

这里有必要说明一下MappingRegistry类,它是AbstractHandlerMethodMapping的内部类,其成员属性如下:

class MappingRegistry {private final Map<T, MappingRegistration<T>> registry = new HashMap<T, MappingRegistration<T>>();// 保存着匹配条件(也就是RequestMappingInfo)和HandlerMethod的对应关系private final Map<T, HandlerMethod> mappingLookup = new LinkedHashMap<T, HandlerMethod>();// 保存着url与匹配条件(也就是RequestMappingInfo)的对应关系,当然这里的url是pattren式的,可以使用通配符。// 由于RequestMappingInfo可以同时使用多种不同的匹配方式而不只是url一种,所以反过来说同一个url就可能有多个RequestMappingInfo与之对应// 这里的RequestMappingInfo其实就是在@RequestMapping中注释的内容private final MultiValueMap<String, T> urlLookup = new LinkedMultiValueMap<String, T>();// 这个Map是spring mvc 4 新增的,保存着name(Controller中处理请求的方法名)与HandlerMethod的对应关系,这个name是从HandlerMethodMappingNamingStrategy的实现类从// HandlerMethod中解析处理的,默认使用的是RequestMappingInfoHandlerMethodMappingNamingStrategy,解析规则是:// 类名里的大写字母组合+"#"+方法名。这个在正常的匹配过程不需要使用,它主要用在MvcUriComponentsBuilder里,可以根据name获取相应的urlprivate final Map<String, List<HandlerMethod>> nameLookup =new ConcurrentHashMap<String, List<HandlerMethod>>();private final Map<HandlerMethod, CorsConfiguration> corsLookup =new ConcurrentHashMap<HandlerMethod, CorsConfiguration>();private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();...
}

注意:带有通配符的路径匹配不在urlLookup属性参数中,只存在了registry。直接匹配所有的参数路径中,才会两者都存。

4.2 AbstractHandlerMethodMapping的初始化

由于AbstractHandlerMethodMapping实现了InitializingBean,因此在其初始化过程中,会调用afterPropertiesSet方法,如下:

public void afterPropertiesSet() {initHandlerMethods();
}

这里我们就可以看出,在初始化AbstractHandlerMethodMapping类的时候,就自动调用了initHandlerMethods方法。这个方法其实就帮我们提前建立起了urlmethod之间的映射关系。在后面处理请求的时候可以根据url直接找到要处理该请求的method。

protected void initHandlerMethods() {if (logger.isDebugEnabled()) {logger.debug("Looking for request mappings in application context: " + getApplicationContext());}// 获取ApplicationContext中的所有bean的nameString[] beanNames = (this.detectHandlerMethodsInAncestorContexts ?BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) :getApplicationContext().getBeanNamesForType(Object.class));// 遍历所有的bean namefor (String beanName : beanNames) {// 如果bean nanme 不是 scopedTarget开头的,则获得其类型if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {Class<?> beanType = null;try {// 获取bean的类型beanType = getApplicationContext().getType(beanName);}catch (Throwable ex) {// An unresolvable bean type, probably from a lazy bean - let's ignore it.if (logger.isDebugEnabled()) {logger.debug("Could not resolve target class for bean with name '" + beanName + "'", ex);}}// 如果beanType不为空,并且是一个处理器,则进行处理if (beanType != null && isHandler(beanType)) {detectHandlerMethods(beanName);}}}// 所有的处理器方法都初始化完成后,调用子类的方法handlerMethodsInitialized(getHandlerMethods());
}

流程:

  1. 获得ApplicationContext中的所有bean的name
  2. 遍历
    1. 如果bean name 不是 scopedTarget开头的,则获得其类型
    2. 如果该bean是一个handler(处理器),则调用detectHandlerMethods()对其进行注册。detectHandlerMethods()方法源码如下:

        

		protected void detectHandlerMethods(final Object handler) {// 获得handler的类型Class<?> handlerType = (handler instanceof String ?getApplicationContext().getType((String) handler) : handler.getClass());// 如果是cglib代理的子对象类型,则返回父类型,否则直接返回传入的类型final Class<?> userType = ClassUtils.getUserClass(handlerType);// 获取当前bean里所有符合Handler要求的Method(也就是获取当前Controller中所有的用来处理请求的方法)Map<Method, T> methods = MethodIntrospector.selectMethods(userType,new MethodIntrospector.MetadataLookup<T>() {@Overridepublic T inspect(Method method) {try {return getMappingForMethod(method, userType);}catch (Throwable ex) {throw new IllegalStateException("Invalid mapping on handler class [" +userType.getName() + "]: " + method, ex);}}});// 将符合要求的methods注册到mappingRegistry中,也就是保存到mappingRegistry的3个map中for (Map.Entry<Method, T> entry : methods.entrySet()) {Method invocableMethod = AopUtils.selectInvocableMethod(entry.getKey(), userType);T mapping = entry.getValue();registerHandlerMethod(handler, invocableMethod, mapping);}}
  1. 获得handler的类型,如果是cglib代理的子对象类型,则返回父类型,否则直接返回传入的类型。
  2. 获取当前bean里所有符合Handler要求的Method,其中会回调getMappingForMethod方法,该方法是个抽象方法,由子类实现。
  3. 将符合要求的methods注册,代码如下:
protected void registerHandlerMethod(Object handler, Method method, T mapping) {// 将method注册到mappingRegistry中this.mappingRegistry.register(mapping, handler, method);
}

MappingRegistry#register()将url和handler之间的映射关系进行了注册,实现如下:

public void register(T mapping, Object handler, Method method) {this.readWriteLock.writeLock().lock();try {// 根据传入的handler和method创建HandlerMethod处理器类型的对象HandlerMethod handlerMethod = createHandlerMethod(handler, method);// 检查是否在mappingLookup已经存在,如果存在而且和现在传入的不同则抛出异常assertUniqueMethodMapping(handlerMethod, mapping);if (logger.isInfoEnabled()) {logger.info("Mapped \"" + mapping + "\" onto " + handlerMethod);}// 添加到mappingLookup中this.mappingLookup.put(mapping, handlerMethod);// 添加到urlLookupList<String> directUrls = getDirectUrls(mapping);for (String url : directUrls) {this.urlLookup.add(url, mapping);}// 添加到nameLookupString name = null;if (getNamingStrategy() != null) {name = getNamingStrategy().getName(handlerMethod, mapping);addMappingName(name, handlerMethod);}// 实例化CorsConfigurationCorsConfiguration corsConfig = initCorsConfiguration(handler, method, mapping);if (corsConfig != null) {this.corsLookup.put(handlerMethod, corsConfig);}this.registry.put(mapping, new MappingRegistration<T>(mapping, handlerMethod, directUrls, name));}finally {this.readWriteLock.writeLock().unlock();}
}

步骤:

  1. 创建HandlerMethod,代码如下:

        

protected HandlerMethod createHandlerMethod(Object handler, Method method) {HandlerMethod handlerMethod;// 如果handler是String类型,那么就是beanNameif (handler instanceof String) {String beanName = (String) handler;// 根据beanName获取对应的beanhandlerMethod = new HandlerMethod(beanName,getApplicationContext().getAutowireCapableBeanFactory(), method);}else {handlerMethod = new HandlerMethod(handler, method);}return handlerMethod;
}
  1. 检查是否在mappingLookup已经存在,如果存在而且和现在传入的不同则抛出异常。代码如下:
private void assertUniqueMethodMapping(HandlerMethod newHandlerMethod, T mapping) {// 检查是否有重复的映射HandlerMethod handlerMethod = this.mappingLookup.get(mapping);if (handlerMethod != null && !handlerMethod.equals(newHandlerMethod)) {throw new IllegalStateException("Ambiguous mapping. Cannot map '" + newHandlerMethod.getBean() + "' method \n" +newHandlerMethod + "\nto " + mapping + ": There is already '" +handlerMethod.getBean() + "' bean method\n" + handlerMethod + " mapped.");}
}
  1. 添加到mappingLookup中。
  2. 添加到urlLookup,其中getDirectUrls–>获得mapping的Path,如果不含有*或者含有?的话,则添加到结果集中。代码如下:
private List<String> getDirectUrls(T mapping) {List<String> urls = new ArrayList<String>(1);for (String path : getMappingPathPatterns(mapping)) {if (!getPathMatcher().isPattern(path)) {urls.add(path);}}return urls;
}

AntPathMatcher#isPattern,如下:

public boolean isPattern(String path) {return (path.indexOf('*') != -1 || path.indexOf('?') != -1);
}
  1. 添加到nameLookup。
  2. 实例化CorsConfiguration,如果不为null,则添加到corsLookup。此处默认返回null,由子类复写。
  3. 添加到registry中。

handlerMethodsInitialized()是模板方法,空实现。

4.3 getHandlerInternal()方法:根据当前的请求url,获取对应的处理器HandlerMathod

getHandlerInternal()是一个很重要的方法,它的实现如下(删去多余代码):

protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {// 1.利用request截取用于匹配的url有效路径(获取当前的请求路径)String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);// 2. 使用lookupHandlerMethod方法通过lookupPath和request找对应的HandlerMethodHandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);// 3. 如果可以找到handlerMethod则调用createWithResolvedBean方法创建新的HandlerMethodreturn (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null); 
}
  1. 利用request对象截取用于匹配的url有效路径。
  2. 使用lookupHandlerMethod方法通过lookupPath和request找HandlerMethod。代码如下:

        

protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {// match是内部类,用于保存匹配条件和HandlerMethodList<Match> matches = new ArrayList<Match>();// 根据请求路径lookupPath获取到匹配条件List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);if (directPathMatches != null) {// 将匹配到的条件添加到matchesaddMatchingMappings(directPathMatches, matches, request);}// 如果不能直接使用lookupPath得到匹配条件,则将所有匹配条件加入到matchesif (matches.isEmpty()) {// No choice but to go through all mappings...addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request);}// 对matches进行排序,并取第一个作为bestMatch。如果前面两个排序相同则抛出异常if (!matches.isEmpty()) {Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));Collections.sort(matches, comparator);if (logger.isTraceEnabled()) {logger.trace("Found " + matches.size() + " matching mapping(s) for [" +lookupPath + "] : " + matches);}Match bestMatch = matches.get(0);if (matches.size() > 1) {if (CorsUtils.isPreFlightRequest(request)) {return PREFLIGHT_AMBIGUOUS_MATCH;}// 如果matches有多个匹配的,则将第2个和第一个进行比较,看顺序是否一样,如果是一样的话,则抛出异常Match secondBestMatch = matches.get(1);if (comparator.compare(bestMatch, secondBestMatch) == 0) {Method m1 = bestMatch.handlerMethod.getMethod();Method m2 = secondBestMatch.handlerMethod.getMethod();throw new IllegalStateException("Ambiguous handler methods mapped for HTTP path '" +request.getRequestURL() + "': {" + m1 + ", " + m2 + "}");}}// 在返回前做一些处理,handleMatch方法的默认实现是将lookupPath设置到request的属性,将更多的参数设置到了request,主要是为了以后使用时方便handleMatch(bestMatch.mapping, lookupPath, request);// 返回匹配的HandlerMethodreturn bestMatch.handlerMethod;}else {// 如果没有匹配的,则调用handleNoMatch方法,子类RequestMappingInfoHandlerMapping进行了重写return handleNoMatch(this.mappingRegistry.getMappings().keySet(), lookupPath, request);}
}

Match内部类讲解:

  1. 根据lookupPath获取到匹配条件,将匹配到的条件添加到matches
  2. 如果不能直接使用lookupPath得到匹配条件,则将所有匹配条件加入到matches
  3. 如果matches非空
    1. 对matches进行排序,并取第一个作为bestMatch,如果前面两个排序相同则抛出异常
    2. 在返回前做一些处理。默认实现是将lookupPath设置到request的属性,子类RequestMappingInfoHandlerMapping进行了重写,将更多的参数设置到了request。主要是为了以后使用时方便
  4. 否则,调用handleNoMatch,默认返回null。

  1. 如果可以找到handlerMethod则调用createWithResolvedBean方法创建新的HandlerMethod。代码如下:
// 该方法用于创建一个HandlerMethod对象
// 此时handlerMethod中只有匹配条件,还没有handler处理器,这个方法就是要将处理器和匹配条件绑定在一起,创建HandlerMethod对象
public HandlerMethod createWithResolvedBean() {Object handler = this.bean;if (this.bean instanceof String) {String beanName = (String) this.bean;handler = this.beanFactory.getBean(beanName);}return new HandlerMethod(this, handler);
}

五、RequestMappingInfoHandlerMapping

RequestMappingInfoHandlerMapping–> 继承自AbstractHandlerMethodMapping。

5.1 成员属性和构造方法

// 对OPTIONS请求的处理时用到
private static final Method HTTP_OPTIONS_HANDLE_METHOD;static {try {HTTP_OPTIONS_HANDLE_METHOD = HttpOptionsHandler.class.getMethod("handle");}catch (NoSuchMethodException ex) {// Should never happenthrow new IllegalStateException("Failed to retrieve internal handler method for HTTP OPTIONS", ex);}
}// 构造方法
protected RequestMappingInfoHandlerMapping() {setHandlerMethodMappingNamingStrategy(new RequestMappingInfoHandlerMethodMappingNamingStrategy());
}

5.2 该类复写了一些方法

5.2.1 getMappingPathPatterns

protected Set<String> getMappingPathPatterns(RequestMappingInfo info) {return info.getPatternsCondition().getPatterns();
}

该方法是在hander注册的时候调用,如下:

5.2.2 getMatchingMapping

检查给定的RequestMappingInfo是否匹配当前的请求,返回RequestMappingInfo,代码如下:

protected RequestMappingInfo getMatchingMapping(RequestMappingInfo info, HttpServletRequest request) {return info.getMatchingCondition(request);
}

5.2.3 getMappingComparator

返回1个比较RequestMappingInfo的Comparator,在有多个Handler匹配当前请求时用到。代码如下:

protected Comparator<RequestMappingInfo> getMappingComparator(final HttpServletRequest request) {return new Comparator<RequestMappingInfo>() {@Overridepublic int compare(RequestMappingInfo info1, RequestMappingInfo info2) {return info1.compareTo(info2, request);}};
}

5.2.4 handleMatchhandleNoMatch

比较简单,这里就不再贴出

六、RequestMappingHandlerMapping

RequestMappingHandlerMapping–> 继承自RequestMappingInfoHandlerMapping。根据在实现Controller接口或者被@Controller注解的类中的在类和方法上声明的@RequestMapping,创建一个 RequestMappingInfo。

6.1 成员属性

// 是否使用后缀匹配(.*)当对请求进行模式匹配时,如果可用时,则/users 对/users.*也匹配.默认是true.
private boolean useSuffixPatternMatch = true;// 是否后缀匹配应该只对ContentNegotiationManager中注册的扩展符匹配时生效.这一般建议减少歧义和避免问题比如当.出现在路径的情况下
private boolean useRegisteredSuffixPatternMatch = false;// 是否有无斜杠都匹配,如果启用的化,则/users 也匹配 /users/.默认是true
private boolean useTrailingSlashMatch = true;// 内容协商
private ContentNegotiationManager contentNegotiationManager = new ContentNegotiationManager();// 这里使用的是EmbeddedValueResolver
private StringValueResolver embeddedValueResolver;// RequestMappingInfo的Builder类,用来创建RequestMappingInfo的
private RequestMappingInfo.BuilderConfiguration config = new RequestMappingInfo.BuilderConfiguration();

6.2 主要方法

6.2.1 覆写了afterPropertiesSet()

public void afterPropertiesSet() {this.config = new RequestMappingInfo.BuilderConfiguration();this.config.setUrlPathHelper(getUrlPathHelper());this.config.setPathMatcher(getPathMatcher());this.config.setSuffixPatternMatch(this.useSuffixPatternMatch);this.config.setTrailingSlashMatch(this.useTrailingSlashMatch);this.config.setRegisteredSuffixPatternMatch(this.useRegisteredSuffixPatternMatch);this.config.setContentNegotiationManager(getContentNegotiationManager());super.afterPropertiesSet();
}

6.2.2 isHandler()

protected boolean isHandler(Class<?> beanType) {return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}

调用链如下:

6.2.3 getMappingForMethod()

使用在类和方法上声明的@RequestMapping来创建RequestMappingInfo。代码如下:

protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {// 1. 根据Method上的@RequestMapping创建RequestMappingInfoRequestMappingInfo info = createRequestMappingInfo(method);if (info != null) {// 2. 根据类上的@RequestMapping创建RequestMappingInfoRequestMappingInfo typeInfo = createRequestMappingInfo(handlerType);if (typeInfo != null) {// 3. 合并info = typeInfo.combine(info);}}return info;
}

createRequestMappingInfo(),如下:

private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) {// 获取@RequestMapping 注解RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class);// 此处返回的都是nullRequestCondition<?> condition = (element instanceof Class ?getCustomTypeCondition((Class<?>) element) : getCustomMethodCondition((Method) element));return (requestMapping != null ? createRequestMappingInfo(requestMapping, condition) : null);
}
  1. 获取@RequestMapping 注解
  2. 获得RequestCondition,此处返回的都是null
  1. 如果requestMapping等于null,则返回null,否则根据RequestMapping创建RequestMappingInfo。代码如下:
protected RequestMappingInfo createRequestMappingInfo(RequestMapping requestMapping, RequestCondition<?> customCondition) {
return RequestMappingInfo.paths(resolveEmbeddedValuesInPatterns(requestMapping.path())).methods(requestMapping.method()).params(requestMapping.params()).headers(requestMapping.headers()).consumes(requestMapping.consumes()).produces(requestMapping.produces()).mappingName(requestMapping.name()).customCondition(customCondition).options(this.config).build();
}

相关文章:【Spring MVC】Spring MVC框架的介绍及其使用方法

                  【Spring MVC】Spring MVC的执行流程与源码分析

相关文章:

【Spring MVC】处理器映射器:AbstractHandlerMethodMapping源码分析

目录 一、继承体系 二、HandlerMapping 三、AbstractHandlerMapping 四、AbstractHandlerMethodMapping 4.1 成员属性 4.1.1 MappingRegistry内部类 4.2 AbstractHandlerMethodMapping的初始化 4.3 getHandlerInternal()方法&#xff1a;根据当前的请求url&#xff0c;…...

网络编程知识整理

目录 1.1 引言 1.2 分层 1.3 TCP/IP的分层 1.4 互联网的地址 1.5 域名服务 1.6 封装 1.7 分用 1.8 端口号 1.1 引言 很多不同的厂家生产各种型号的计算机&#xff0c;它们运行完全不同的操作系统&#xff0c;但 T C P / I P协议族允许它们互相进行通信。这一点很让人感…...

【小白友好】leetcode 移动零

https://leetcode.cn/problems/move-zeroes/description/ 小白思想 思想上还是首先开一个指针i&#xff0c;i从左到右扫每一个元素&#xff0c;i每发现一个0&#xff0c;就把这个0推到最后&#xff0c;这样i到最后就可以了。 这个和删除元素那个题解的小白思想和一模一样&am…...

迭代、递归、尾递归实现斐波那契数列的第n项

1.什么是斐波那契数列&#xff1a; 斐波那契数&#xff0c;亦称之为斐波那契数列&#xff08;意大利语&#xff1a; Successione di Fibonacci)&#xff0c;又称黄金分割数列、费波那西数列、费波拿契数、费氏数列和兔子数列&#xff0c;指的是这样一个数列&#xff1a;0、1、…...

vulnhub靶场之driftingblues-1

一.环境搭建 1.靶场描述 get flags difficulty: easy about vm: tested and exported from virtualbox. dhcp and nested vtx/amdv enabled. you can contact me by email (it should be on my profile) for troubleshooting or questions. 2.靶场下载 https://www.vulnhub.…...

NGINX服务器配置实现加密的WebSocket连接WSS协议

一、背景 最近在做小程序开发&#xff0c;需要在nginx中配置websocket加密模式&#xff0c;即wss。初次配置wss时&#xff0c;踩了两个小时的坑&#xff0c;本文将踩坑过程分享给大家&#xff0c;有需要用到的伙伴可以直接copy即可实现&#xff0c;节省宝贵时间。 二、WebSo…...

5个免费文章神器,用来改写文章太方便了

在当今信息爆炸的时代&#xff0c;内容创作和编辑是网络世界中至关重要的环节。然而&#xff0c;有时候我们可能会遇到一些内容需要进行改写或者重组的情况。为了提高效率&#xff0c;让这一过程更加顺畅&#xff0c;我们可以借助一些免费的文章神器来帮助我们完成这一任务。下…...

详细教程!VMware Workstation Pro16 安装 + 创建 win7 虚拟机!

嚯嚯嚯&#xff0c;很多宝子都想拥有自己不同的操作系统环境&#xff0c;用于学习或项目搭建。买服务器费钱&#xff0c;虚拟机则成为了一个很好的选择。本文详细介绍VMware Workstation Pro 16安装及win7虚拟机创建&#xff0c;保姆级教程奉上&#xff01; 一、准备工作 VMw…...

Python文件和异常(二)

目录 三、异常 &#xff08;一&#xff09;处理 ZeroDivisionError 异常 &#xff08;二&#xff09;使用 try-except 代码块 &#xff08;三&#xff09;使用异常避免崩溃 &#xff08;四&#xff09;else 代码块 &#xff08;五&#xff09;处理 FileNotFoundError 异常…...

大模型+影像:智能手机“上春山”

这个春节假期&#xff0c;一首《上春山》火了。吃瓜群众热热闹闹学了一个假期的“春山学”&#xff0c;了解了抢占C位的各种技巧。 假期过去&#xff0c;开工大吉&#xff0c;手机行业开始抢占今年的C位。那么问题来了&#xff0c;今年智能手机最大的机会点在哪里&#xff1f;答…...

8-pytorch-损失函数与反向传播

b站小土堆pytorch教程学习笔记 根据loss更新模型参数 1.计算实际输出与目标之间的差距 2.为我们更新输出提供一定的依据&#xff08;反向传播&#xff09; 1 MSEloss import torch from torch.nn import L1Loss from torch import nninputstorch.tensor([1,2,3],dtypetorch.fl…...

MySQL高级特性篇(8)-数据库连接池的配置与优化

MySQL数据库连接池的配置与优化 MySQL数据库是当前最流行的关系型数据库管理系统之一&#xff0c;高效的数据库连接池配置与优化是提高数据库性能和并发性能的重要手段。本文将介绍MySQL数据库连接池的配置与优化&#xff0c;并提供详细示例。 1. 连接池的作用与优势 数据库…...

mac下使用jadx反编译工具

直接执行步骤&#xff1a; 1.创建 jadx目录 mkdir jadx2.将存储库克隆到目录 git clone https://github.com/skylot/jadx.git 3. 进入 jadx目录 cd jadx 4.执行编译 等待片刻 ./gradlew dist出现这个就代表安装好了。 5.最后找到 jadx-gui 可执行文件&#xff0c;双击两下…...

分布式一致性软件-zookeeper

在我们进行软件开发过程中&#xff0c;为了实现某个功能可能借助多个软件&#xff0c;如存储数据的数据库软件&#xff1a;MySQL&#xff0c;Redis&#xff1b;消息中间件&#xff1a;rocketMq&#xff0c;kafka等。那么在分布式系统中&#xff0c;如果想实现数据一致性&#x…...

企业计算机服务器中了babyk勒索病毒怎么办?Babyk勒索病毒解密数据恢复

随着网络技术的应用与普及&#xff0c;越来越多的企业采用了数字化办公模式&#xff0c;数字化办公模式可以为企业提供强有力的数据支撑&#xff0c;可以为企业的发展方向与产品业务调整做好基础工作。但网络是一把双刃剑&#xff0c;在为企业提供便利的同时&#xff0c;也为企…...

板块一 Servlet编程:第五节 Cookie对象全解 来自【汤米尼克的JAVAEE全套教程专栏】

板块一 Servlet编程&#xff1a;第五节 Cookie对象全解 一、什么是CookieCookie的源码 二、Cookie的具体操作&#xff08;1&#xff09;创建Cookie&#xff08;2&#xff09;获取Cookie&#xff08;3&#xff09;设置Cookie的到期时间&#xff08;4&#xff09;设置Cookie的路径…...

自动驾驶---Motion Planning之Path Boundary

1 背景 在上文《自动驾驶---Motion Planning之LaneChange》中,笔者提到过两种LaneChange的思路,这里再简单回顾一下:(1)利用Routing和周围环境的信息,决定是否进行换道的决策;(2)采用的博弈思想(蒙特卡洛树搜索---MCTS)决定是否进行换道的决策。不管是变道,避让还是…...

Leetcode 3048. Earliest Second to Mark Indices I

Leetcode 3048. Earliest Second to Mark Indices I 1. 解题思路2. 代码实现 题目链接&#xff1a;3048. Earliest Second to Mark Indices I 1. 解题思路 这一题的话基础的思路就是二分法查找最小的可以将所有的数字都mark上的最小位置。 因此&#xff0c;这里的问题就会变…...

从源码学习单例模式

单例模式 单例模式是一种设计模式&#xff0c;常用于确保一个类只有一个实例&#xff0c;并提供一个全局访问点。这意味着无论在程序的哪个地方&#xff0c;只能创建一个该类的实例&#xff0c;而不会出现多个相同实例的情况。 在单例模式中&#xff0c;常用的实现方式包括懒汉…...

axios介绍和使用

1. Axios是什么 Axios框架全称&#xff08;ajax – I/O – system&#xff09; Axios是一个基于Promise的JavaScript HTTP客户端&#xff0c;用于浏览器和Node.js环境。它可以发送HTTP请求并支持诸如请求和响应拦截、转换数据、取消请求以及自动转换JSON数据等功能。 Axios提…...

redis雪崩问题

Redis雪崩问题是指在Redis缓存系统中&#xff0c;由于某些原因导致大量缓存数据同时失效或过期&#xff0c;导致所有请求都直接访问数据库&#xff0c;从而引发数据库性能问题甚至宕机的情况。 造成Redis雪崩问题的原因主要有以下几个&#xff1a; 缓存数据同时失效&#xff…...

[SUCTF 2019]EasySQL1 题目分析与详解

一、题目介绍 1、题目来源&#xff1a; BUUCTF网站&#xff0c;网址&#xff1a;https://buuoj.cn/challenges 2、题目描述&#xff1a; 通过以上信息&#xff0c;拿到flag。 二、解题思路 首先打开靶机&#xff0c;尝试输入1查看回显&#xff0c;回显如图所示&#xff1a;…...

TestNG与ExtentReport单元测试导出报告文档

TestNG与ExtentReport集成 目录 1 通过实现ITestListener的方法添加Reporter log 1.1 MyTestListener设置 1.2 输出结果 2 TestNG与ExtentReporter集成 2.1 项目结构 2.2 MyExtentReportListener设置 2.3 单多Suite、Test组合测试 2.3.1 单Suite单Test 2.3…...

【JavaEE】_form表单构造HTTP请求

目录 1. form表单的格式 1.1 form表单的常用属性 1.2 form表单的常用搭配标签&#xff1a;input 2. form表单构造GET请求实例 3. form表单构造POST请求实例 4. form表单构造法的缺陷 对于客户端浏览器&#xff0c;以下操作即构造了HTTP请求&#xff1a; 1. 直接在浏览器…...

Mysql中INFORMATION_SCHEMA虚拟库使用

虚拟库字段讲解 #查看INFORMATION_SCHEMA的表信息 DESC information_schema.tables; 重要列&#xff1a; TABLE_SCHEMA #表所在的库 TABLE_NAME #表名 ENGINE #表的存储引擎 TABLE_ROWS #表的行数 DATA_LENGTH #表数据行占用的字节数 AVG_ROW_LENGTH #平均行长度 INDEX_LENGTH…...

【《高性能 MySQL》摘录】第 2 章 MySQL 基准测试

文章目录 2.1 为什么需要基准测试2.2 基准测试的策略2.2.1 测试何种指标 2.3 基准测试方法2.3.1 设计和规划基准测试2.3.2 基准测试应该运行多长时间2.3.3 获取系统性能和状态2.3.4 获得准确的测试结果2.3.5 运行基准测试并分析结果2.3.6 绘图的重要性 2.4 基准测试工具…...

常用的Web应用程序的自动测试工具有哪些

在Web应用程序的自动化测试领域&#xff0c;有许多流行的工具可供选择。以下是一些常用的Web自动化测试工具&#xff1a; 1. Selenium - Selenium是最流行的开源Web应用程序自动化测试套件之一。 - 它支持多种编程语言&#xff0c;如Java、C#、Python、Ruby等。 …...

人工智能与开源机器学习框架

链接&#xff1a;华为机考原题 TensorFlow是一个开源的机器学习框架&#xff0c;由Google开发和维护。它提供了一个针对神经网络和深度学习的强大工具集&#xff0c;能够帮助开发人员构建和训练各种机器学习模型。 TensorFlow的基本概念包括&#xff1a; 张量&#xff08;Ten…...

高通XBL阶段读取分区

【需求】&#xff1a; 在某些场景下&#xff0c;需要在XBL阶段读取分区数据&#xff0c;需要验证xbl阶段方案 这里主要以裸分区为例&#xff0c;比如oem分区。 1、创建一个1MB大小的oem.img&#xff0c;写入内容“test oem partition” 创建方式&#xff1a; dd if/dev/null …...

[极客大挑战2019]upload

该题考点&#xff1a;后缀黑名单文件内容过滤php木马的几种书写方法 phtml可以解析php代码&#xff1b;<script language"php">eval($_POST[cmd]);</script> 犯蠢的点儿&#xff1a;利用html、php空格和php.不解析<script language"php"&…...