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

SpringBoot第二天

目录

1.Web开发

1.1简介

1.2SpringBoot对静态资源的映射规则

1.3模板引擎

1.3.1引入thymeleaf;

1.3.2Thymeleaf语法

1.3.2.1标准表达式语法

        1.变量表达式

1.3.2.2表达式支持的语法

1.3.2.3常用的thymeleaf标签

1.4Springboot整合springmvc

1.4.1Springmvc的自动解管理

1.4.1.1中央转发器

1.4.1.2控制器

1.4.1.3视图解析器自动管理

1.4.1.4静态资源访问

1.4.1.5消息转换和格式化

1.4.1.6欢迎页面的自动配置

1.4.2Springboot扩展springmvc 

1.4.2.1在容器中注册视图控制器(请求转发)

1.4.2.2注册格式化器

1.4.2.3消息转换器扩展fastjson

1.4.2.4拦截器注册

1.5配置嵌入式服务器

1.5.1如何定制和修改Servlet容器的相关配置;

1.5.2注册Servlet三大组件【Servlet、Filter、Listener】

1.6使用外置的Servlet容器


1.Web开发

1.1简介

使用SpringBoot
1)、创建SpringBoot应用,选中我们需要的模块;
2)、SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运行起来
3)、自己编写业务代码;

自动配置原理?
这个场景SpringBoot帮我们配置了什么?能不能修改?能修改哪些配置?能不能扩展?xxx

1.2SpringBoot对静态资源的映射规则

@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties implements ResourceLoaderAware {
//可以设置和静态资源有关的参数,缓存时间等
WebMvcAuotConfiguration:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
     if (!this.resourceProperties.isAddMappings()) {
           logger.debug("Default resource handling disabled");
           return;
      } 
Integer cachePeriod = this.resourceProperties.getCachePeriod();
if (!registry.hasMappingForPattern("/webjars/**")) {
     customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META‐INF/resources/webjars/").setCachePeriod(cachePeriod));
} 
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
//静态资源文件夹映射
if (!registry.hasMappingForPattern(staticPathPattern)) {
      customizeResourceHandlerRegistration(registry.
addResourceHandler(staticPathPattern).addResourceLocations(this.resourceProperties.getStaticLocations()).setCachePeriod(cachePeriod));
}
} /
/配置欢迎页映射
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(
       ResourceProperties resourceProperties) {
       return new WelcomePageHandlerMapping(resourceProperties.getWelcomePage(),
this.mvcProperties.getStaticPathPattern());
}
//配置喜欢的图标
@Configuration
@ConditionalOnProperty(value = "spring.mvc.favicon.enabled", matchIfMissing = true)
public static class FaviconConfiguration {
       private final ResourceProperties resourceProperties;
       public FaviconConfiguration(ResourceProperties resourceProperties) {
            this.resourceProperties = resourceProperties;
}
 @Bean
public SimpleUrlHandlerMapping faviconHandlerMapping() {
       SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
       mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
       //所有 **/favicon.ico
            mapping.setUrlMap(Collections.singletonMap("**/favicon.ico",
faviconRequestHandler());
return mapping;
} 
@Bean
public ResourceHttpRequestHandler faviconRequestHandler() {
       ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
       requestHandler.setLocations(this.resourceProperties.getFaviconLocations());
       return requestHandler;
 }
}

1)、所有 /webjars/** ,都去 classpath:/META-INF/resources/webjars/ 找资源;

webjars:以jar包的方式引入静态资源;WebJars - Web Libraries in Jars

 

        localhost:8080/webjars/jquery/3.3.1/jquery.js 

<!‐‐引入jquery‐webjar‐‐>在访问的时候只需要写webjars下面资源的名称即可
<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId>
    <version>3.3.1</version>
</dependency>

2)、"/**" 访问当前项目的任何资源,都去(静态资源的文件夹)找映射

"classpath:/META‐INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/"
"/":当前项目的根路径

localhost:8080/abc === 去静态资源文件夹里面找abc

3)、欢迎页; 静态资源文件夹下的所有index.html页面;被"/**"映射;

localhost:8080/ index页面

1.3模板引擎

JSPVelocityFreemarkerThymeleaf

SpringBoot推荐的Thymeleaf

语法更简单,功能更强大;

1.3.1引入thymeleaf

        在pom.xml中引入

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

        从spring父文件中能看到Springboot2.0.1所使用的thymeleaf版本是3.0.9

        springBoot启动的时候会自动配置

org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration

        从ThymeleafAutoConfiguration的源代码中我们可以得知ThymeleafProperties中配置了Thymeleaf的规则

public class ThymeleafProperties {
    private static final Charset DEFAULT_ENCODING;
    public static final String DEFAULT_PREFIX = "classpath:/templates/";
    public static final String DEFAULT_SUFFIX = ".html";
    private boolean checkTemplate = true;
    private boolean checkTemplateLocation = true;
    private String prefix = "classpath:/templates/";
    private String suffix = ".html";
    private String mode = "HTML";
    private Charset encoding;
    private boolean cache;
}

我们使用html作为模板,而且默认的前缀是放在classpath:/templates/下,后缀是.html

当然这些属性我们都可以通过application.properties来修改我们采用默认即可。

示例

  1. templates下创建一个success.html
  2. html中引入thymeleaf的命名空间
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
  3. 创建一个Controller提供一个访问的方法
    @RequestMapping("/success")
    public String hello(Model model){
        model.addAttribute("hello","<h1>zhangsan</h1>");
        return "success";
    }
  4. thymeleaf模板中取值
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
            "http://www.w3.org/TR/html4/loose.dtd">
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <title>Title</title>
    </head>
    <body>
    <div  th:text="${hello}"> </div>
    </body>
    </html>

1.3.2Thymeleaf语法

1.3.2.1标准表达式语法
        1.变量表达式

变量表达式即OGNL表达式或Spring EL表达式(Spring术语中也叫model attributes)。如下所示: ${session.user.name}

它们将以HTML标签的一个属性来表示:

<span th:text="${book.author.name}"> 

        2.选择(星号)表达式

        选择表达式很像变量表达式,不过它们用一个预先选择的对象来代替上下文变量容器(map)来执行,如下: *{customer.name}

        被指定的objectth:object属性定义:

<div th:object="${book}"> 
 ... 
 <span th:text="*{title}">...</span> 
 ... 
</div>

        3.文字国际化表达式

        文字国际化表达式允许我们从一个外部文件获取区域文字信息(.properties),用Key索引Value,还可以提供一组参数(可选).

#{main.title}

        4.URL表达式

URL表达式指的是把一个有用的上下文或回话信息添加到URL,这个过程经常被叫做URL重写。不需要指定项目名字
@{/order/list} 

URL还可以设置参数:

@{/order/details(id=${orderId})} 

让我们看这些表达式:

<form th:action="@{/createOrder}"> 
<a href="main.html" rel="external nofollow" th:href="@{/main}" rel="external n
1.3.2.2表达式支持的语法

字面(Literals)

  • 文本文字(Text literals): 'one text', 'Another one!',…
  • 数字文本(Number literals): 0, 34, 3.0, 12.3,…
  • 布尔文本(Boolean literals): true, false
  • 空(Null literal): null
  • 文字标记(Literal tokens): one, sometext, main,…

文本操作(Text operations)

  • 字符串连接(String concatenation): +
  • 文本替换(Literal substitutions): |The name is ${name}|

算术运算(Arithmetic operations)

  • 二元运算符(Binary operators): +, -, *, /, %
  • 减号(单目运算符)Minus sign (unary operator): -

布尔操作(Boolean operations)

  • 二元运算符(Binary operators):and, or
  • 布尔否定(一元运算符)Boolean negation (unary operator):!, not

比较和等价(Comparisons and equality)

  • 比较(Comparators): >, <, >=, <= (gt, lt, ge, le)
  • 等值运算符(Equality operators):==, != (eq, ne)

条件运算符(Conditional operators)

If-then: (if) ? (then)

If-then-else: (if) ? (then) : (else)

Default: (value) ?: (defaultvalue)

示例代码

'User is of type ' + (${user.isAdmin()} ? 'Administrator' : (${user.type} ?: 'Unknown'))

1.3.2.3常用的thymeleaf标签

关键字

功能介绍

案例

th:id

替换id

<input th:id="'xxx' + ${collect.id}"/>

th:text

文本替换

<p th:text="${collect.description}">description</p>

th:utext

支持html的文本替换

<p th:utext="${htmlcontent}">conten</p>

th:object

替换对象

<div th:object="${session.user}">

th:value

属性赋值

<input th:value="${user.name}" />

th:onclick

点击事件

th:οnclick="'getCollect()'"

th:each

属性赋值

tr th:each="user,userStat:${users}">

th:if

判断条件

<a th:if="${userId == collect.userId}" >

th:unless

和th:if判断相反

<a th:href="@{/login}" rel="external nofollow" rel="external nofollow" rel="external nofollow" th:unless=${session.user != null}>Login</a>

th:href

链接地址

<a th:href="@{/login}" rel="external nofollow" rel="external nofollow" rel="external nofollow" th:unless=${session.user != null}>Login</a> />

th:switch

多路选择 配合th:case 使用

<div th:switch="${user.role}">

th:case

th:switch的一个分支

<p th:case="'admin'">User is an administrator</p>

th:fragment

布局标签,定义一个代码片段,方便其它地方引用

<div th:fragment="alert">

th:include

布局标签,替换内容到引入的文件

<head th:include="layout :: htmlhead" th:with="title='xx'"></head> />

th:replace

布局标签,替换整个标签到引入的文件

<div th:replace="fragments/header :: title"></div>

th:selected

selected选择框 选中

th:selected="(${xxx.id} == ${configObj.dd})"

th:src

图片类地址引入

<img class="img-responsive" alt="App Logo" th:src="@{/img/logo.png}" />

th:action

表单提交的地址

<form action="subscribe.html" th:action="@{/subscribe}">

        标签测试

        模板:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Title</title>
</head>
<body>
<div  th:text="${hello}" th:id="${hello.toUpperCase()}">xxxx</div>
<input th:value="${user.getUsername()}">
<hr>
<div th:object="${user}">
<span th:text="*{username}"></span>

</div>


<a th:href="" th:if="${user.getAge() == 2}" >年龄</a>

<a  th:class="${user.getAge() > 2}?'class1':'class2'" >年龄</a>

<p th:if="${user.score >= 60 and user.score < 85}">B</p>
<p th:if="${user.score < 60}">C</p>
<p th:if="${user.score > 85}">优秀</p>


<span th:switch="${user.gender}">
    <p th:case="1">男</p>
    <p th:case="2">女</p>
</span>


<table>

    <tr th:each="a,aState:${uList}">
        <td th:text="${a.username}"></td>
        <td th:text="${a.password}"></td>
        <td th:text="${aState.index}"></td>
    </tr>
</table>

</body>
</html>

        Controller中给数据

@RequestMapping("/success")
public String hello(HttpServletRequest req, HttpSession httpSession, Model model){
    model.addAttribute("hello","<h1>renliang</h1>");
    User user = new User();
    user.setPassword("111");
    user.setUsername("renliang");
    user.setAge(1);
    user.setScore(78);
    user.setGender(2);
    List<User> uList = new ArrayList<>();
    for (int i = 0; i < 10; i++){
        User u = new User();
        u.setUsername("renliang"+i);
        u.setPassword("111"+i);

        uList.add(u);
    }

   // httpSession.setAttribute("user", user);
    model.addAttribute("user", user);
    model.addAttribute("uList", uList);
    return "success";
}

1.4Springboot整合springmvc

    https://docs.spring.io/spring-boot/docs/2.0.2.RELEASE/reference/htmlsingle/#boot-features-spring-mvc

        学习springmvc和springboot的自动配置我们必须对springmvc的组件足够了解,起码知道怎么用。Springmvc的组件基本都被springboot来做了自动的配置。

1.4.1Springmvc的自动解管理

  1. 中央转发器(DispatcherServlet
  2. 控制器
  3. 视图解析器
  4. 静态资源访问
  5. 消息转换器
  6. 格式化
  7. 静态资源管理
  8. 1.4.1.1中央转发器
    1.         Xml无需配置

      1. <servlet>
            <servlet-name>chapter2</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>chapter2</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>

                中央转发器被springboot自动接管,不再需要我们在web.xml中配置,我们现在的项目也不是web项目,也不存在web.xml,

        org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\

1.4.1.2控制器

        控制器Controller在springboot的注解扫描范围内自动管理。

1.4.1.3视图解析器自动管理

Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.

ContentNegotiatingViewResolver:组合所有的视图解析器的;

曾经的配置文件无需再配

<bean id="de" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/jsp/"></property>
    <property name="suffix" value="*.jsp"></property>
</bean>

        源码:

public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) {
    ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
    resolver.setContentNegotiationManager((ContentNegotiationManager)beanFactory.getBean(ContentNegotiationManager.class));
    resolver.setOrder(-2147483648);
    return resolver;
}

        当我们做文件上传的时候我们也会发现multipartResolver自动被配置好的页面

<form action="/upload" method="post" enctype="multipart/form-data">
    <input name="pic" type="file">
    <input type="submit">
</form>

        Controller

@ResponseBody
@RequestMapping("/upload")
public String upload(@RequestParam("pic")MultipartFile file, HttpServletRequest request){
    String contentType = file.getContentType();
    String fileName = file.getOriginalFilename();
    /*System.out.println("fileName-->" + fileName);
    System.out.println("getContentType-->" + contentType);*/
    //String filePath = request.getSession().getServletContext().getRealPath("imgupload/");
    String filePath = "D:/imgup/";
    try {
        this.uploadFile(file.getBytes(), filePath, fileName);
    } catch (Exception e) {
        // TODO: handle exception
    }

    return "success";
}

public static void uploadFile(byte[] file, String filePath, String fileName) throws Exception {
    File targetFile = new File(filePath);
    if(!targetFile.exists()){
        targetFile.mkdirs();
    }
    FileOutputStream out = new FileOutputStream(filePath+fileName);
    out.write(file);
    out.flush();
    out.close();
}

文件上传大小可以通过配置来修改

打开application.properties, 默认限制是10MB,我们可以任意修改

1.4.1.4静态资源访问

        参见4.2

1.4.1.5消息转换和格式化

        Springboot自动配置了消息转换器

        格式化转换器的自动注册

        时间类型我们可以在这里修改

        在配置文件中指定好时间的模式我们就可以输入了

1.4.1.6欢迎页面的自动配置

        Springboot自动指定resources下的index.html

1.4.2Springboot扩展springmvc 

        在实际开发中springboot并非完全自动化,很多跟业务相关我们需要自己扩展,springboot给我提供了接口。

        我们可以来通过实现WebMvcConfigurer接口来扩展

public interface WebMvcConfigurer {
    default void configurePathMatch(PathMatchConfigurer configurer) {
    }

    default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    }

    default void configureAsyncSupport(AsyncSupportConfigurer configurer) {
    }

    default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    }

    default void addFormatters(FormatterRegistry registry) {
    }

    default void addInterceptors(InterceptorRegistry registry) {
    }

    default void addResourceHandlers(ResourceHandlerRegistry registry) {
    }

    default void addCorsMappings(CorsRegistry registry) {
    }

    default void addViewControllers(ViewControllerRegistry registry) {
    }

    default void configureViewResolvers(ViewResolverRegistry registry) {
    }

    default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
    }

    default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {
    }

    default void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    }

    default void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
    }

    default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
    }

    default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
    }

    @Nullable
    default Validator getValidator() {
        return null;
    }

    @Nullable
    default MessageCodesResolver getMessageCodesResolver() {
        return null;
    }
}
1.4.2.1在容器中注册视图控制器(请求转发)

        创建一个MyMVCCofnig实现WebMvcConfigurer接口,实现一下addViewControllers方法我们完成通过/tx访问,转发到success.html工作

@Configuration
public class MyMVCCofnig implements WebMvcConfigurer{
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/tx").setViewName("success");
    }
}
1.4.2.2注册格式化器

        用来可以对请求过来的日期格式化的字符串来做定制化。当然通过application.properties配置也可以办到。

@Override
public void addFormatters(FormatterRegistry registry) {
    registry.addFormatter(new Formatter<Date>() {
        @Override
        public String print(Date date, Locale locale) {
            return null;
        }
        @Override
        public Date parse(String s, Locale locale) throws ParseException {
            return new SimpleDateFormat("yyyy-MM-dd").parse(s);
        }
    });
}
1.4.2.3消息转换器扩展fastjson

        在pom.xml中引入fastjson

<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>fastjson</artifactId>
   <version>1.2.47</version>
</dependency>

        配置消息转换器,添加fastjson

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    FastJsonHttpMessageConverter fc = new FastJsonHttpMessageConverter();
    FastJsonConfig fastJsonConfig = new FastJsonConfig();
    fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
    fc.setFastJsonConfig(fastJsonConfig);
    converters.add(fc);
}

        在实体类上可以继续控制

public class User
{

    private  String username;

    private  String password;

    private int age;

    private int score;

    private int gender;

    @JSONField(format = "yyyy-MM-dd")
    private Date date;

}
1.4.2.4拦截器注册

1.创建拦截器

public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("前置拦截");
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("后置拦截");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("最终拦截");
    }
}

拦截器注册

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/hello2");
}

1.5配置嵌入式服务器

1.5.1如何定制和修改Servlet容器的相关配置;

修改和server有关的配置(ServerProperties);

server.port=8081
server.context‐path=/tx
server.tomcat.uri‐encoding=UTF‐8

1.5.2注册Servlet三大组件【Servlet、Filter、Listener】

        由于SpringBoot默认是以jar包的方式启动嵌入式的Servlet容器来启动SpringBootweb应用,没有web.xml文件。

        1.servlet

//注册三大组件
@Bean
public ServletRegistrationBean myServlet(){
    ServletRegistrationBean registrationBean = new ServletRegistrationBean(newMyServlet(),"/myServlet");
    return registrationBean;
}

        2. FilterRegistrationBean

@Bean
public FilterRegistrationBean myFilter(){
    FilterRegistrationBean registrationBean = new FilterRegistrationBean();
    registrationBean.setFilter(new MyFilter());
    registrationBean.setUrlPatterns(Arrays.asList("/hello","/myServlet"));
    return registrationBean;
}

        3. ServletListenerRegistrationBean

@Bean
public ServletListenerRegistrationBean myListener(){
    ServletListenerRegistrationBean<MyListener> registrationBean = newServletListenerRegistrationBean<>(new MyListener());
    return registrationBean;
}

SpringBoot帮我们自动SpringMVC的时候,自动的注册SpringMVC的前端控制器;DispatcherServlet
DispatcherServletAutoConfiguration中:

@Bean(name = DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)
@ConditionalOnBean(value = DispatcherServlet.class, name =
DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public ServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet) {
    ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet, this.serverProperties.getServletMapping());
    //默认拦截: / 所有请求;包静态资源,但是不拦截jsp请求; /*会拦截jsp
    //可以通过server.servletPath来修改SpringMVC前端控制器默认拦截的请求路径
    registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
    registration.setLoadOnStartup(this.webMvcProperties.getServlet().getLoadOnStartup());
    if (this.multipartConfig != null) {registration.setMultipartConfig(this.multipartConfig);}
    return registration;
}

1.6使用外置的Servlet容器

嵌入式Servlet容器:应用打成可执行的jar

优点:简单、便携;

缺点:默认不支持JSP、优化定制比较复杂.;

        外置的Servlet容器:外面安装Tomcat---应用war包的方式打包;

步骤

1)、必须创建一个war项目;(利用idea创建好目录结构)

2)、将嵌入式的Tomcat指定为provided 

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring‐boot‐starter‐tomcat</artifactId>
    <scope>provided</scope>
</dependency>

3)配置项目的目录结构

 

4)部署Tomcat

3)、必须编写一个SpringBootServletInitializer的子类,并调用configure方法

public class ServletInitializer extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        //传入SpringBoot应用的主程序
        return application.sources(SpringBoot04WebJspApplication.class);
    }
}

4)、启动服务器就可以使用;

原理

jar包:执行SpringBoot主类的main方法,启动ioc容器,创建嵌入式的Servlet容器;

war包:启动服务器,服务器启动SpringBoot应用【SpringBootServletInitializer】,启动ioc容器;


http://www.kler.cn/a/586088.html

相关文章:

  • 深搜专题9:取数游戏
  • C++11多线程,锁与条件变量
  • 【CXX】6.7 SharedPtr<T> — std::shared_ptr<T>
  • 网络_面试_HTTP请求报文和HTTP响应报文
  • RGV调度(四)--排队算法
  • VLAN,DHCP实验访问物理机
  • TDengine 配置 ODBC 数据源
  • 工程实践:如何使用SU17无人机来实现室内巡检任务
  • 达梦数据库中插入导出图片的方法与应用
  • 通过 CSS 的 命名页面(Named Pages) 技术实现作用域隔离,实现 @page 样式仅影响当前组件
  • K8S之QoS详解
  • JVM垃圾收集器相关面试题(1)
  • app=Flask(__name__)中的__name__的意义
  • Git版本控制系统详解
  • [MYSQL]关于join的慢sql优化
  • 《实战AI智能体》DeepSearcher 的架构设计
  • ChatGPT、DeepSeek、Grok:AI 语言模型的差异与应用场景分析
  • 学习15天:pytest
  • react(一):特点-基本使用-JSX语法
  • 用Deep seek解析ChatGPT打造数字虚拟人