【源码分析设计模式 10】SpringMVC中的建造者模式(1),快手 算法 面试

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

@Override

public void roofed() {

System.out.println(" 高楼的透明屋顶 ");

}

}

4、指挥者HouseDirector


package designMode.advance.builder;

public class HouseDirector {

HouseBuilder houseBuilder = null;

//构造器传入 houseBuilder

public HouseDirector(HouseBuilder houseBuilder) {

this.houseBuilder = houseBuilder;

}

//通过setter 传入 houseBuilder

public void setHouseBuilder(HouseBuilder houseBuilder) {

this.houseBuilder = houseBuilder;

}

//如何处理建造房子的流程,交给指挥者

public House constructHouse() {

houseBuilder.buildBasic();

houseBuilder.buildWalls();

houseBuilder.roofed();

return houseBuilder.buildHouse();

}

}

5、测试类


package designMode.advance.builder;

public class Client {

public static void main(String[] args) {

//盖普通房子

CommonHouse commonHouse = new CommonHouse();

//准备创建房子的指挥者

HouseDirector houseDirector = new HouseDirector(commonHouse);

//完成盖房子,返回产品(普通房子)

House house = houseDirector.constructHouse();

System.out.println(“--------------------------”);

//盖高楼

HighBuilding highBuilding = new HighBuilding();

//重置建造者

houseDirector.setHouseBuilder(highBuilding);

//完成盖房子,返回产品(高楼)

houseDirector.constructHouse();

}

}

6、控制台输出


六、建造者模式在SpringMVC中的实现

=====================

1、在springMVC中,我们就可以看到建造者模式的身影。


springMVC在构建UriComponents的内容时,就用到了建造者模式,我们先来看看UriComponents这个类是提供了哪些Components

public abstract class UriComponents implements Serializable {

private static final String DEFAULT_ENCODING = “UTF-8”;

// 用于分割uri的正则表达式,下面会说到

private static final Pattern NAMES_PATTERN = Pattern.compile(“\{([^/]+?)\}”);

private final String scheme;

private final String fragment;

protected UriComponents(String scheme, String fragment) {

this.scheme = scheme;

this.fragment = fragment;

}

// 多个Components对应的getter方法

/**

  • 返回URL的scheme.

*/

public final String getScheme() {

return this.scheme;

}

/**

  • 返回URL的fragment.

*/

public final String getFragment() {

return this.fragment;

}

/**

  • 返回URL的schemeSpecificPar

*/

public abstract String getSchemeSpecificPart();

/**

  • 返回userInfo

*/

public abstract String getUserInfo();

/**

  • 返回URL的host

*/

public abstract String getHost();

/**

  • 返回URL的port

*/

public abstract int getPort();

/**

  • 返回URL的path

*/

public abstract String getPath();

/**

  • 返回URL的path部分的集合

*/

public abstract List getPathSegments();

/**

  • 返回URL的query部分

*/

public abstract String getQuery();

/**

  • 返回URL的query参数map

*/

public abstract MultiValueMap<String, String> getQueryParams();

/**

  • 将URL的components用特定的编码规则编码并返回,默认为utf-8

*/

public final UriComponents encode() {

try {

return encode(DEFAULT_ENCODING);

}

catch (UnsupportedEncodingException ex) {

// should not occur

throw new IllegalStateException(ex);

}

}

/**

  • 编码的抽象方法,传入相应的编码规则

*/

public abstract UriComponents encode(String encoding) throws UnsupportedEncodingException;

/**

  • 将URL中的模板参数换成对应的值

*/

public final UriComponents expand(Map<String, ?> uriVariables) {

Assert.notNull(uriVariables, “‘uriVariables’ must not be null”);

return expandInternal(new MapTemplateVariables(uriVariables));

}

/**

  • 将URL中的模板参数换成对应的值,输入为数组

*/

public final UriComponents expand(Object… uriVariableValues) {

Assert.notNull(uriVariableValues, “‘uriVariableValues’ must not be null”);

return expandInternal(new VarArgsTemplateVariables(uriVariableValues));

}

/**

  • 将URL中的模板参数换成对应的值,输入为UriTemplateVariables

*/

public final UriComponents expand(UriTemplateVariables uriVariables) {

Assert.notNull(uriVariables, “‘uriVariables’ must not be null”);

return expandInternal(uriVariables);

}

/**

  • 将URL中的模板参数换成对应的值的最终的实现方法

*/

abstract UriComponents expandInternal(UriTemplateVariables uriVariables);

/**

  • 处理URL

*/

public abstract UriComponents normalize();

/**

  • 返回URL的string

*/

public abstract String toUriString();

/**

  • 返回URI格式的方法

*/

public abstract URI toUri();

@Override

public final String toString() {

return toUriString();

}

/**

  • 将这些Components的值赋给其builder类

*/

protected abstract void copyToUriComponentsBuilder(UriComponentsBuilder builder);

上面的代码不包括UriComponents类下其余的静态辅助方法,单单从此类的包含多种components中,就可以看出UriComponents的复杂程度。这些components大都对应了url的某个部分,能帮助springMVC对请求的url内容进行识别。springMVC就是通过将uri构建成这个类,再对uri进行处理的。

2、UriComponentsBuilder


那么springMVC究竟是如何让请求的uri生成相应的UriComponents类呢?就要看看UriComponentsBuilder这个类了。

首先看看它的两个构造函数:

/**

  • 默认构造方法,其中path的构造类为CompositePathComponentBuilder,它为UriComponentsBuilder的内部静态类,主要实现对url的path部分进行构造。

*/

protected UriComponentsBuilder() {

this.pathBuilder = new CompositePathComponentBuilder();

}

/**

  • 创建一个传入UriComponentsBuilder类的深拷贝对象

*/

protected UriComponentsBuilder(UriComponentsBuilder other) {

this.scheme = other.scheme;

this.ssp = other.ssp;

this.userInfo = other.userInfo;

this.host = other.host;

this.port = other.port;

this.pathBuilder = other.pathBuilder.cloneBuilder();

this.queryParams.putAll(other.queryParams);

this.fragment = other.fragment;

}

由于url的path部分是比较复杂的,这边springMVC用了内部类的方式,为path单独加了两个builder类,分别是CompositePathComponentBuilder、FullPathComponentBuilder,这里就不扩展来说了。看完了UriComponentsBuilder的构造方法,我们来看它是如何将给定的uri生成为相应的UriComponents的。这里就从比较容易理解的fromUriString方法入手吧:

// 静态方法,从uri的字符串中获得uri的各种要素

public static UriComponentsBuilder fromUriString(String uri) {

Assert.notNull(uri, “URI must not be null”);

// 利用正则表达式,获得uri的各个组成部分

Matcher matcher = URI_PATTERN.matcher(uri);

if (matcher.matches()) {

UriComponentsBuilder builder = new UriComponentsBuilder();

// 获得对应要素的字符串

String scheme = matcher.group(2);

String userInfo = matcher.group(5);

String host = matcher.group(6);

String port = matcher.group(8);

String path = matcher.group(9);

String query = matcher.group(11);

String fragment = matcher.group(13);

// uri是否透明的标志位

boolean opaque = false;

// uri存在scheme且后面不跟:/则为不透明uri

例如mailto:java-net@java.sun.com

if (StringUtils.hasLength(scheme)) {

String rest = uri.substring(scheme.length());

if (!rest.startsWith(“😕”)) {

opaque = true;

}

}

builder.scheme(scheme);

// 如果为不透明uri,则具备ssp,需要设置ssp

if (opaque) {

String ssp = uri.substring(scheme.length()).substring(1);

if (StringUtils.hasLength(fragment)) {

ssp = ssp.substring(0, ssp.length() - (fragment.length() + 1));

}

builder.schemeSpecificPart(ssp);

}

// 如果为绝对uri(通常意义上的uri),则设置各个component

else {

builder.userInfo(userInfo);

builder.host(host);

if (StringUtils.hasLength(port)) {

builder.port(port);

}

builder.path(path);

builder.query(query);

}

if (StringUtils.hasText(fragment)) {

最后

这份文档从构建一个键值数据库的关键架构入手,不仅带你建立起全局观,还帮你迅速抓住核心主线。除此之外,还会具体讲解数据结构、线程模型、网络框架、持久化、主从同步和切片集群等,帮你搞懂底层原理。相信这对于所有层次的Redis使用者都是一份非常完美的教程了。

image

整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~

你的支持,我的动力;祝各位前程似锦,offer不断!!!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

Length(port)) {

builder.port(port);

}

builder.path(path);

builder.query(query);

}

if (StringUtils.hasText(fragment)) {

最后

这份文档从构建一个键值数据库的关键架构入手,不仅带你建立起全局观,还帮你迅速抓住核心主线。除此之外,还会具体讲解数据结构、线程模型、网络框架、持久化、主从同步和切片集群等,帮你搞懂底层原理。相信这对于所有层次的Redis使用者都是一份非常完美的教程了。

[外链图片转存中…(img-QJPvzbEp-1713668122833)]

整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~

你的支持,我的动力;祝各位前程似锦,offer不断!!!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-rjDTzHY9-1713668122834)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 15
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值