从零开始构建高效Spring Boot应用:实战案例与最佳实践

news2025/3/3 20:58:50

摘要

本文旨在为初学者及有一定基础的开发者提供一份详尽的指南,以帮助大家深入理解并掌握如何使用Spring Boot框架来快速开发企业级应用程序。通过实际案例分析、代码示例以及架构设计思路分享,读者不仅能够学习到理论知识,还能获得宝贵的实践经验。

目录

  • 摘要
  • 目录
  • 引言
  • Spring Boot简介
  • 环境搭建
  • 创建第一个Spring Boot项目
  • 配置管理
  • 数据访问层
  • Web服务开发
  • 安全机制实现
  • 日志记录
  • 单元测试与集成测试
  • 部署上线
  • 总结与展望

引言

随着微服务架构逐渐成为主流趋势之一,选择一个合适的后端技术栈变得尤为重要。Spring Boot凭借其强大的生态支持和简便易用的特点,在众多解决方案中脱颖而出。本篇文章将带领大家一起探索Spring Boot的世界,解锁其背后的强大功能。

Spring Boot简介

定义

Spring Boot是由Pivotal团队提供的全新框架,用来简化新Spring应用的初始搭建以及开发过程。

特点

  • 自动配置:基于约定优于配置的原则。
  • 起步依赖:简化Maven或Gradle配置文件。
  • 嵌入式服务器:无需额外安装Tomcat等容器即可运行Web应用。
  • 命令行界面:支持直接生成项目结构。

环境搭建

首先确保你的机器上已经安装了以下软件:

  • JDK(建议版本1.8及以上)
  • MavenGradle
  • IDE 如 IntelliJ IDEA 或 Eclipse

安装JDK

  1. 下载JDK:访问Oracle官网或OpenJDK下载适合你操作系统的JDK版本。
  2. 安装JDK:按照安装向导进行安装。
  3. 配置环境变量:
    • JAVA_HOME:指向JDK的安装路径。
    • PATH:添加%JAVA_HOME%\bin(Windows)或$JAVA_HOME/bin(Linux/Mac)。

安装Maven

  1. 下载Maven:访问Maven官网下载最新版本的Maven。
  2. 解压下载的文件到指定目录。
  3. 配置环境变量:
    • MAVEN_HOME:指向Maven的解压路径。
    • PATH:添加%MAVEN_HOME%\bin(Windows)或$MAVEN_HOME/bin(Linux/Mac)。

安装IDE

  1. 下载IntelliJ IDEA或Eclipse:访问IntelliJ IDEA官网或Eclipse官网下载适合你操作系统的版本。
  2. 安装并启动IDE。

创建第一个Spring Boot项目

使用Spring Initializr

  1. 访问Spring Initializr官网。
  2. 填写项目信息:
    • Project:选择Maven Project。
    • Language:选择Java。
    • Spring Boot:选择最新的稳定版本。
    • Project Metadata
      • Group:输入你的组织ID(如com.example)。
      • Artifact:输入项目名称(如myapp)。
      • Name:输入项目名称(如myapp)。
      • Description:输入项目描述。
      • Package name:输入包名(如com.example.myapp)。
      • Packaging:选择Jar。
      • Java:选择Java版本(如8或11)。
  3. 添加依赖:
    • Spring Web:用于创建Web应用。
    • Spring Data JPA:用于数据访问。
    • MySQL Driver:用于连接MySQL数据库。
    • Spring Security:用于安全认证。
    • Lombok:用于减少样板代码。
  4. 点击“Generate”按钮下载zip包。
  5. 解压下载的zip包,并在IDE中导入项目。

项目结构

导入项目后,可以看到如下主要组成部分:

  • src/main/java:存放Java源代码。
  • src/main/resources:放置静态资源文件。
  • pom.xml:项目构建脚本。

编辑主类

编辑主类Application.java,添加注解@SpringBootApplication标记这是一个Spring Boot启动类,并在其中编写入口方法:

package com.example.myapp;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

运行项目

保存后右键选择Run As -> Java Application,如果一切正常你应该能看到控制台输出类似以下信息:

Tomcat started on port(s): 8080 (http) with context path ''
Started Application in 2.376 seconds (JVM running for 3.459)

这表明我们的第一个Spring Boot程序已经成功运行起来了!

配置管理

Spring Boot提倡外部化配置,允许我们在不修改代码的情况下调整应用程序的行为。常见的做法是通过application.propertiesapplication.yml文件来进行设置。

application.properties 示例

src/main/resources目录下创建application.properties文件,并添加以下内容:

server.port=8081
spring.application.name=myapp

application.yml 示例

同样地,可以在src/main/resources目录下创建application.yml文件,并添加以下内容:

server:
  port: 8081
spring:
  application:
    name: myapp

多环境配置

可以通过不同的Profile特性根据不同环境加载特定配置文件。例如,创建application-dev.propertiesapplication-prod.properties文件:

application-dev.properties
server.port=8081
spring.datasource.url=jdbc:mysql://localhost:3306/mydb_dev
spring.datasource.username=root
spring.datasource.password=root
application-prod.properties
server.port=8082
spring.datasource.url=jdbc:mysql://localhost:3306/mydb_prod
spring.datasource.username=root
spring.datasource.password=root

在启动时指定Profile:

mvn spring-boot:run -Dspring.profiles.active=dev

数据访问层

为了演示如何操作数据库,这里我们选用MySQL作为例子。首先需要添加相应的依赖项至pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

实体类

定义一个简单的User实体类:

package com.example.myapp.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    private String email;

    // Getters and Setters
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

Repository接口

定义一个UserRepository接口继承自JpaRepository

package com.example.myapp.repository;

import com.example.myapp.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {
}

Service层

定义UserService类来处理业务逻辑:

package com.example.myapp.service;

import com.example.myapp.entity.User;
import com.example.myapp.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public List<User> findAll() {
        return userRepository.findAll();
    }

    public Optional<User> findById(Long id) {
        return userRepository.findById(id);
    }

    public User save(User user) {
        return userRepository.save(user);
    }

    public void deleteById(Long id) {
        userRepository.deleteById(id);
    }
}

Web服务开发

借助于Spring MVC的强大支持,我们可以轻松地构建RESTful API。下面展示一个简单的控制器用于处理HTTP请求:

UserController

创建UserController类:

package com.example.myapp.controller;

import com.example.myapp.entity.User;
import com.example.myapp.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping
    public List<User> getAllUsers() {
        return userService.findAll();
    }

    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        return userService.findById(id)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }

    @PostMapping
    public User createUser(@RequestBody User user) {
        return userService.save(user);
    }

    @PutMapping("/{id}")
    public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User user) {
        if (userService.findById(id).isPresent()) {
            user.setId(id);
            return ResponseEntity.ok(userService.save(user));
        } else {
            return ResponseEntity.notFound().build();
        }
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        if (userService.findById(id).isPresent()) {
            userService.deleteById(id);
            return ResponseEntity.noContent().build();
        } else {
            return ResponseEntity.notFound().build();
        }
    }
}

安全机制实现

安全对于任何互联网产品来说都是至关重要的环节。Spring Security提供了丰富的功能来保护你的应用免受攻击。可以通过引入相关依赖并配置SecurityConfig类来启用认证授权等功能。

添加依赖

pom.xml中添加Spring Security依赖:

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

配置Security

创建SecurityConfig类:

package com.example.myapp.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/users/**").hasRole("USER")
                .anyRequest().permitAll()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("user").password(passwordEncoder().encode("password")).roles("USER")
            .and()
            .withUser("admin").password(passwordEncoder().encode("admin")).roles("ADMIN");
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

日志记录

良好的日志系统可以帮助我们更好地追踪问题所在。Spring Boot默认集成了Logback作为日志框架。你可以在logback-spring.xml中自定义日志格式、级别等属性。

logback-spring.xml

src/main/resources目录下创建logback-spring.xml文件:

<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml"/>

    <logger name="com.example.myapp" level="DEBUG" additivity="false">
        <appender-ref ref="STDOUT"/>
    </logger>

    <root level="INFO">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

单元测试与集成测试

编写高质量的测试用例有助于提高软件质量。Spring Boot推荐使用JUnit配合Mockito进行单元测试,而对于更复杂的场景,则可以考虑采用Spring Test模块提供的功能来进行集成测试。

添加依赖

pom.xml中添加测试依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <scope>test</scope>
</dependency>

单元测试

创建UserServiceTest类:

package com.example.myapp.service;

import com.example.myapp.entity.User;
import com.example.myapp.repository.UserRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.Optional;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.*;

class UserServiceTest {

    @InjectMocks
    private UserService userService;

    @Mock
    private UserRepository userRepository;

    @BeforeEach
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testFindById() {
        User mockUser = new User(1L, "John Doe", "john.doe@example.com");
        when(userRepository.findById(1L)).thenReturn(Optional.of(mockUser));

        User result = userService.findById(1L);

        assertEquals(mockUser, result);
    }

    @Test
    public void testSaveUser() {
        User newUser = new User(null, "Jane Doe", "jane.doe@example.com");
        User savedUser = new User(1L, "Jane Doe", "jane.doe@example.com");
        when(userRepository.save(newUser)).thenReturn(savedUser);

        User result = userService.save(newUser);

        assertEquals(savedUser, result);
    }

    @Test
    public void testDeleteById() {
        doNothing().when(userRepository).deleteById(1L);

        userService.deleteById(1L);

        verify(userRepository, times(1)).deleteById(1L);
    }
}

集成测试

创建UserControllerIntegrationTest类:

package com.example.myapp.controller;

import com.example.myapp.entity.User;
import com.example.myapp.repository.UserRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;

import java.util.Arrays;
import java.util.List;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;

@SpringBootTest
@AutoConfigureMockMvc
class UserControllerIntegrationTest {

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private UserRepository userRepository;

    @BeforeEach
    public void setUp() {
        userRepository.saveAll(Arrays.asList(
            new User(1L, "John Doe", "john.doe@example.com"),
            new User(2L, "Jane Doe", "jane.doe@example.com")
        ));
    }

    @Test
    public void testGetAllUsers() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/users")
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(MockMvcResultMatchers.jsonPath("$.length()").value(2));
    }

    @Test
    public void testGetUserById() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/users/1")
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(MockMvcResultMatchers.jsonPath("$.name").value("John Doe"));
    }

    @Test
    public void testCreateUser() throws Exception {
        User newUser = new User(null, "Alice", "alice@example.com");

        mockMvc.perform(MockMvcRequestBuilders.post("/users")
                .contentType(MediaType.APPLICATION_JSON)
                .content("{\"name\":\"Alice\",\"email\":\"alice@example.com\"}"))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(MockMvcResultMatchers.jsonPath("$.name").value("Alice"));
    }

    @Test
    public void testUpdateUser() throws Exception {
        User updatedUser = new User(1L, "John Updated", "john.updated@example.com");

        mockMvc.perform(MockMvcRequestBuilders.put("/users/1")
                .contentType(MediaType.APPLICATION_JSON)
                .content("{\"id\":1,\"name\":\"John Updated\",\"email\":\"john.updated@example.com\"}"))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(MockMvcResultMatchers.jsonPath("$.name").value("John Updated"));
    }

    @Test
    public void testDeleteUser() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.delete("/users/1"))
                .andExpect(MockMvcResultMatchers.status().isNoContent());

        mockMvc.perform(MockMvcRequestBuilders.get("/users/1")
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(MockMvcResultMatchers.status().isNotFound());
    }
}

部署上线

当所有开发工作完成后,下一步就是将应用部署到生产环境中。Spring Boot支持多种方式打包发布,包括传统的WAR包形式以及更加轻量级的JAR包。通常情况下推荐后者,因为它包含了运行所需的一切依赖。

打包

执行以下命令生成可执行jar文件:

mvn clean package -DskipTests

启动

之后只需一条简单的命令就能启动服务:

java -jar target/myapp.jar

总结与展望

通过以上步骤的学习,相信你对如何利用Spring Boot快速搭建高效的应用已经有了比较全面的认识。当然这只是冰山一角,Spring Boot还有更多高级特性和插件等待着你去发掘。希望这篇文章能为你开启一段精彩的编程之旅!


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2309178.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SQL经典题型

查询不在表里的数据&#xff0c;一张学生表&#xff0c;一张学生的选课表&#xff0c;要求查出没有选课的学生&#xff1f; select students.student_name from students left join course_selection on students.student_idcourse_selection.student_id where course_selecti…

【deepseek第二课】docker部署dify,配置私有化知识库,解决网络超时,成功安装

【deepseek第二课】docker部署dify&#xff0c;配置私有化知识库&#xff0c;解决网络超时&#xff0c;成功安装 1. dify安装1.1 官网安装文档介绍1.2 安装报错&#xff0c;网络连接问题使用镜像加速器处理1.3 dify后台启动很多docker进程 2. 页面探索2.1 设置管理账号2.2 添加…

P8651 [蓝桥杯 2017 省 B] 日期问题--注意日期问题中2月的天数 / if是否应该连用

P8651 [P8651 [蓝桥杯 2017 省 B] 日期问题--注意日期问题中2月的天数 / if是否应该连用 题目 分析代码 题目 分析 代码中巧妙的用到3重循环&#xff0c;完美的解决了输出的顺序问题【题目要求从小到大】 需要注意的是2月的值&#xff0c;在不同的年份中应该更新2月的值 还有…

动态规划多阶段报童模型,c++ 实现, java 实现

借助 chaptgpt 和 deepseek&#xff0c;成功实现了c上的多阶段报童模型的动态规划。花费了几天&#xff0c;将以前的 java 程序用 c 实现。 文章目录 C 代码Java 代码 总结&#xff1a; c 还是比 java 快点&#xff0c;30个阶段快了零点几秒c 使用了 unordered_map &#xff0…

PE文件结构详解(DOS头/NT头/节表/导入表)使用010 Editor手动解析notepad++.exe的PE结构

一&#xff1a;DOS部分 DOS部分分为DOS MZ文件头和DOS块&#xff0c;其中DOS MZ头实际是一个64位的IMAGE_DOS——HEADER结构体。 DOS MZ头部结构体的内容如下&#xff0c;我们所需要关注的是前面两个字节&#xff08;e_magic&#xff09;和后面四个字节&#xff08;e_lfanew&a…

[含文档+PPT+源码等]精品基于Python实现的vue3+Django计算机课程资源平台

基于Python实现的Vue3Django计算机课程资源平台的背景&#xff0c;可以从以下几个方面进行阐述&#xff1a; 一、教育行业发展背景 1. 教育资源数字化趋势 随着信息技术的快速发展&#xff0c;教育资源的数字化已成为不可逆转的趋势。计算机课程资源作为教育领域的重要组成部…

vue3中ref和reactive响应式数据、ref模板引用(组合式和选项式区别)、组件ref的使用

目录 Ⅰ.ref 1.基本用法&#xff1a;ref响应式数据 2.ref模板引用 3.ref在v-for中的模板引用 ​4.ref在组件上使用 ​5.TS中ref数据标注类型 Ⅱ.reactive 1.基本用法&#xff1a;reactive响应式数据 2.TS中reactive标注类型 Ⅲ.ref和reactive的使用场景和区别 Ⅳ.小结…

Oracle VM VirtualBox 7.1 安装与虚拟机创建全流程指南(Windows平台)

一、软件定位与核心功能 Oracle VM VirtualBox 是开源跨平台虚拟化工具&#xff0c;支持在 Windows、Linux、macOS 系统上创建和管理虚拟机&#xff08;VM&#xff09;&#xff0c;其核心功能包括&#xff1a; 多系统兼容&#xff1a;可安装 Windows、Ubuntu、CentOS 等 50 操…

细说 Java GC 垃圾收集器

一、GC目标 业务角度&#xff0c;我们需要追求2个指标&#xff1a; 低延迟&#xff08;Latency&#xff09;&#xff1a;请求必须多少毫秒内完成响应&#xff1b;高吞吐&#xff08;Throughput&#xff09;&#xff1a;每秒完成多少次事务。 两者通常存在权衡关系&#xff0…

第2章 windows故障排除(网络安全防御实战--蓝军武器库)

网络安全防御实战--蓝军武器库是2020年出版的&#xff0c;已经过去3年时间了&#xff0c;最近利用闲暇时间&#xff0c;抓紧吸收&#xff0c;总的来说&#xff0c;第2章开始带你入门了&#xff0c;这里给出了几个windows重要的工具&#xff0c;说实话&#xff0c;好多我也是第一…

量子关联特性的多维度探索:五量子比特星型系统与两量子比特系统的对比分析

模拟一个五量子比特系统&#xff0c;其中四个量子比特&#xff08;编号为1, 2, 3, 4&#xff09;分别与第五个量子比特&#xff08;编号为5&#xff09;耦合&#xff0c;形成一个星型结构。分析量子比特1和2的纠缠熵随时间的变化。 系统的哈密顿量H描述了量子比特间的相互作用…

HarmonyOS学习第12天:解锁表格布局的奥秘

表格布局初相识 不知不觉&#xff0c;我们在 HarmonyOS 的学习旅程中已经走到了第 12 天。在之前的学习里&#xff0c;我们逐步掌握了 HarmonyOS 开发的各种基础与核心技能&#xff0c;比如组件的基本使用、布局的初步搭建等&#xff0c;这些知识就像一块块基石&#xff0c;为我…

《Python实战进阶》No 11:微服务架构设计与 Python 实现

第11集&#xff1a;微服务架构设计与 Python 实现 2025年3月3日更新了代码和微服务运行后的系统返回信息截图&#xff0c;所有代码在 python3.11.5虚拟环境下运行通过。 微服务架构通过将复杂应用拆分为独立部署的小型服务&#xff0c;显著提升了系统的可扩展性和维护性。本集…

Android15 Camera HAL Android.bp中引用Android.mk编译的libB.so

背景描述 Android15 Camera HAL使用Android.bp脚本来构建系统。假设Camera HAL中引用了另外一个HAL实现的so &#xff08;例如VPU HAL&#xff09;&#xff0c; 恰巧被引用的这个VPU HAL so是用Android.mk构建的&#xff0c;那Camera HAL Android.bp在直接引用这个Android.mk编…

P8720 [蓝桥杯 2020 省 B2] 平面切分--set、pair

P8720 [蓝桥杯 2020 省 B2] 平面切分--set、pair 题目 分析一、pair1.1pair与vector的区别1.2 两者使用场景两者组合使用 二、set2.1核心特点2.2set的基本操作2.3 set vs unordered_set示例&#xff1a;统计唯一单词数代码 题目 分析 大佬写的很明白&#xff0c;看这儿 我讲讲…

postgresql源码学习(60)—— VFD的作用及机制

首先VFD是Virtual File Descriptor&#xff0c;即虚拟文件描述符&#xff0c;既然是虚拟的&#xff0c;一定先有物理的。 一、 物理文件描述符&#xff08;File Descriptor, FD&#xff09; 1. 什么是 FD 它是操作系统提供给用户程序访问和操作文件或其他 I/O 资源的抽象接口…

【CSS—前端快速入门】CSS 选择器

CSS 1. CSS介绍 1.1 什么是CSS? CSS(Cascading Style Sheet)&#xff0c;层叠样式表&#xff0c;用于控制页面的样式&#xff1b; CSS 能够对网页中元素位置的排版进行像素级精确控制&#xff0c;实现美化页面的效果&#xff1b;能够做到页面的样式和 结构分离&#xff1b; 1…

Linux安装jdk,node,mysql,redis

准备工作&#xff1a; 1.安装VMware软件&#xff0c;下载CentOs7镜像文件&#xff0c;在VMware安装CentOs7 2.宿主机安装Xshell用来操作linux 3. .宿主机安装Xftp用来在宿主机和虚拟机的linux传输文件 案例1&#xff1a;在 /home/soft文件夹解压缩jdk17&#xff0c;并配置环…

深度求索(DeepSeek)的AI革命:NLP、CV与智能应用的技术跃迁

Deepseek官网&#xff1a;DeepSeek 引言&#xff1a;AI技术浪潮中的深度求索 近年来&#xff0c;人工智能技术以指数级速度重塑全球产业格局。在这场技术革命中&#xff0c;深度求索&#xff08;DeepSeek&#xff09;凭借其前沿的算法研究、高效的工程化能力以及对垂直场景的…

Minio搭建并在SpringBoot中使用完成用户头像的上传

Minio使用搭建并上传用户头像到服务器操作,学习笔记 Minio介绍 minio官网 MinIO是一个开源的分布式对象存储服务器&#xff0c;支持S3协议并且可以在多节点上实现数据的高可用和容错。它采用Go语言开发&#xff0c;拥有轻量级、高性能、易部署等特点&#xff0c;并且可以自由…