【全面解析】Spring Boot 中的单元测试:从基础到实战

2024-09-01 04:04

本文主要是介绍【全面解析】Spring Boot 中的单元测试:从基础到实战,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 【全面解析】Spring Boot 中的单元测试:从基础到实战
    • 引言
    • 1. 单元测试基础知识
      • 1.1单元测试的基本概念
      • 1.2 测试驱动开发 (TDD) 与行为驱动开发 (BDD)
      • 1.3 测试金字塔
      • 1.4 JUnit 和 TestNG 概览
      • 1.5 断言框架介绍 (Hamcrest, AssertJ)
    • 2. Spring Boot 测试框架和工具
      • 2.1 Spring Boot 测试模块简介
      • 2.2 使用 Spring Boot Starter Test
      • 2.3 Mockito 和 PowerMock 工具
      • 2.4 Spring TestContext Framework
      • 2.5 常见注解和配置选项
    • 3. 设置测试环境
      • 3.1 创建 Spring Boot 项目
      • 3.2 添加依赖项
      • 3.3 配置测试资源文件
      • 3.4 构建工具和 IDE 集成
    • 4. 编写简单的单元测试
      • 4.1 示例应用概述
      • 4.2 编写第一个测试类
      • 4.3 测试生命周期和方法
      • 4.4 使用断言进行验证
    • 5. 模拟对象和依赖注入
      • 5.1 为什么需要模拟对象
      • 5.2 使用 Mockito 创建模拟对象
      • 5.3 注入模拟对象到被测类
      • 5.4 测试依赖注入
      • 5.5 验证方法调用
    • 6. 集成测试和端到端测试
      • 6.1 集成测试 vs 单元测试
      • 6.2 使用 Spring Boot 进行集成测试
      • 6.3 端到端测试简介
      • 6.4 Web 测试支持 (Spring MVC Test)
    • 7. 高级主题
      • 7.1 异常处理测试
      • 7.2 异步操作测试
      • 7.3 测试数据库交互
      • 7.4 性能测试
      • 7.5 并行测试执行
    • 8. 最佳实践和技巧
    • 9. 总结与展望

【全面解析】Spring Boot 中的单元测试:从基础到实战

引言

在当今快速发展的软件行业中,编写高质量的应用程序变得越来越重要。随着软件复杂性的增加,确保代码的稳定性和可靠性成为了开发过程中的关键因素。单元测试作为一种重要的质量保证手段,可以帮助开发者在早期发现并修复问题,从而提高软件产品的整体质量。本节将介绍单元测试的基本概念、其重要性以及如何在 Spring Boot 应用中实施单元测试。

什么是单元测试?

单元测试是一种软件测试方法,它通过检查软件中的最小可测试单元(如函数或方法)是否按预期工作来验证代码的正确性。这种测试通常由开发者自己编写,旨在确保每个小部分都能单独正确运行。

单元测试的重要性

  • 缺陷早期检测:单元测试可以在代码合并到主分支之前就发现潜在的问题,减少了后期调试的成本。
  • 增强代码质量:良好的单元测试可以作为代码质量的指标,鼓励开发者编写更清晰、更易于理解的代码。
  • 重构的安全网:当开发者需要对现有代码进行重构时,单元测试可以提供安全网,确保重构后代码的功能仍然正确。
  • 文档作用:单元测试可以作为活文档,帮助新成员更快地理解代码的行为和功能。

Spring Boot 应用中的单元测试

Spring Boot 是一个流行的 Java 框架,用于简化基于 Spring 的应用开发。它内置了大量自动配置机制,使得开发者能够专注于业务逻辑而不是框架配置。在 Spring Boot 应用中进行单元测试不仅可以确保应用的核心功能正常运作,还可以帮助开发者更好地理解和维护代码。

本文目标概述

本文旨在全面介绍如何在 Spring Boot 应用中实施单元测试。我们将从基础知识讲起,逐步深入到具体的实践案例。通过学习本文,您将能够掌握以下内容:

  • 单元测试的基础概念。
  • 如何利用 JUnit 和 Mockito 等工具进行单元测试。
  • 如何使用 Spring Boot 提供的测试支持来编写高效的单元测试。
  • 最佳实践和技巧,帮助您在实际开发中更有效地运用单元测试。

1. 单元测试基础知识

1.1单元测试的基本概念

单元测试是一种白盒测试技术,它针对软件的最小可测试单元(通常是方法或函数)。这些测试通常由开发者编写,并且是自动化运行的。它们有助于验证函数或方法的输出是否符合预期,同时也帮助确保当修改了代码后,这些功能仍然能够按照设计意图工作。

1.2 测试驱动开发 (TDD) 与行为驱动开发 (BDD)

  • 测试驱动开发 (TDD): TDD 是一种开发方法,强调在编写实际代码之前先编写测试。这有助于开发者更早地考虑需求,并有助于创建更健壮的设计。
  • 行为驱动开发 (BDD): BDD 是一种扩展了 TDD 的方法,它更加注重描述软件的行为而非内部实现。BDD 使用自然语言描述测试场景,以便利益相关者更容易理解。

1.3 测试金字塔

测试金字塔是一种模型,展示了不同类型的测试在软件测试策略中的分布。从下至上分别是单元测试、集成测试和端到端测试。理想的分布是底层的单元测试最多,上层的端到端测试最少。

1.4 JUnit 和 TestNG 概览

  • JUnit: 是最常用的 Java 测试框架之一,提供了简单的方法来编写可重复运行的测试。JUnit 5(也称为 JUnit Jupiter)是最新版本,引入了许多改进,包括模块化设计和更好的扩展性。
  • TestNG: TestNG 是另一个强大的测试框架,它提供了一些 JUnit 不具备的功能,如并行测试执行和更灵活的测试配置。

1.5 断言框架介绍 (Hamcrest, AssertJ)

  • Hamcrest: Hamcrest 是一个轻量级的框架,用于创建匹配器,以进行更复杂的断言。它可以与 JUnit 或 TestNG 结合使用。
  • AssertJ: AssertJ 是一个富有表现力的断言库,它提供了丰富的 API,使断言更加清晰和简洁。

2. Spring Boot 测试框架和工具

2.1 Spring Boot 测试模块简介

Spring Boot 提供了一个名为 spring-boot-starter-test 的启动器依赖,其中包含了常用的测试框架和工具,如 JUnit、Mockito、Spring Test、Hamcrest 等。

2.2 使用 Spring Boot Starter Test

要在 Spring Boot 项目中添加单元测试支持,只需要在项目的 pom.xmlbuild.gradle 文件中添加 spring-boot-starter-test 依赖即可。例如,在 Maven 项目中,可以添加如下依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions>
</dependency>

2.3 Mockito 和 PowerMock 工具

  • Mockito: Mockito 是一个流行的 Java 模拟框架,用于创建模拟对象,以隔离被测试组件的外部依赖。这有助于编写更纯净的单元测试。
  • PowerMock: PowerMock 是一个扩展框架,可以用来模拟不可模拟的对象,如静态方法、构造函数等。在大多数情况下,推荐优先使用 Mockito,但在某些特定情况下 PowerMock 可能会更有用。

2.4 Spring TestContext Framework

Spring TestContext Framework 是 Spring 提供的一套测试支持框架,它允许在不同的上下文中运行测试,比如完全隔离的上下文、部分隔离的上下文等。这有助于更好地控制测试的执行环境。

2.5 常见注解和配置选项

  • @RunWith(SpringRunner.class): 指定使用 Spring 测试运行器来执行测试。
  • @SpringBootTest: 表示这是一个 Spring Boot 应用的测试类,可以加载整个 Spring 应用上下文。
  • @TestConfiguration: 标记一个配置类,用于提供测试期间所需的 Bean 定义。
  • @MockBean: 用于在测试中声明一个模拟 Bean。
  • @Autowired: 用于注入 Bean 到测试类中。

3. 设置测试环境

3.1 创建 Spring Boot 项目

在开始之前,我们需要创建一个新的 Spring Boot 项目。有多种方式可以创建 Spring Boot 项目,包括使用 Spring Initializr 网站手动配置,或者通过集成开发环境(IDE)如 IntelliJ IDEA 或 Eclipse 创建。

1. 使用 Spring Initializr 创建项目:

  • 访问 Spring Initializr。
  • 选择项目类型(如 Maven),选择 Java 作为编程语言,并指定项目元数据。
  • 选择依赖项,确保至少选择了 Spring WebSpring Boot DevTools
  • 选择 spring-boot-starter-test 作为测试依赖。

2. 使用 IDE 创建项目:

  • 打开 IntelliJ IDEA 或 Eclipse。
  • 选择新建 Spring Boot 项目。
  • 按照向导步骤完成项目配置,确保包含必要的依赖。

3.2 添加依赖项

无论采用哪种方式创建项目,确保 pom.xmlbuild.gradle 文件中包含以下依赖项:

<!-- pom.xml 示例 -->
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency>
</dependencies>

对于 Gradle 用户,应该在 build.gradle 文件中添加:

// build.gradle 示例
dependencies {implementation 'org.springframework.boot:spring-boot-starter-web'testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

3.3 配置测试资源文件

在 Spring Boot 应用中,测试资源文件通常位于 src/test/resources 目录下。这里可以放置各种配置文件,例如 application.properties 或 application.yml 文件,专门用于测试环境。此外,还可以存放 SQL 脚本等其他测试所需资源。

3.4 构建工具和 IDE 集成

大多数现代 IDE 都支持直接运行和调试单元测试。例如,在 IntelliJ IDEA 中,可以通过右键点击测试类并选择 “Run” 或 “Debug” 来执行测试。同时,IDE 还提供了查看测试结果、断点调试等功能。


4. 编写简单的单元测试

4.1 示例应用概述

为了演示如何编写单元测试,我们将创建一个简单的 Spring Boot 应用,该应用包含一个 HelloWorldService 类,用于提供一个简单的问候信息。

package com.example.demo;import org.springframework.stereotype.Service;@Service
public class HelloWorldService {public String sayHello(String name) {return "Hello " + name + "!";}
}

4.2 编写第一个测试类

现在我们来编写一个测试类来测试上面定义的服务。

package com.example.demo;import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import static org.junit.jupiter.api.Assertions.assertEquals;@SpringBootTest
class HelloWorldServiceTest {@Autowiredprivate HelloWorldService helloWorldService;@Testvoid contextLoads() {// 这个测试只是为了确认 Spring 上下文可以成功加载assertNotNull(helloWorldService);}@Testvoid shouldReturnDefaultMessage() {// 给定String name = "Alice";// 当String result = helloWorldService.sayHello(name);// 然后assertEquals("Hello Alice!", result);}
}

4.3 测试生命周期和方法

JUnit 5 提供了多种注解来控制测试的生命周期,包括 @BeforeAll, @BeforeEach, @AfterEach, 和 @AfterAll。这些注解可用于设置和清理测试环境。

@Test
void shouldReturnDefaultMessage() {// 给定String name = "Alice";// 当String result = helloWorldService.sayHello(name);// 然后assertEquals("Hello Alice!", result);
}

4.4 使用断言进行验证

在测试方法中,我们使用 assertEquals 方法来验证 sayHello 方法返回的字符串是否符合预期。JUnit 5 提供了丰富的断言方法,包括但不限于 assertNotNull, assertTrue, assertFalse 等。


5. 模拟对象和依赖注入

5.1 为什么需要模拟对象

在编写单元测试时,通常需要隔离被测对象(SUT, System Under Test)与其他对象的交互。模拟对象(mocks)就是为此目的而创建的假对象,它们可以模拟真实对象的行为而不执行任何实际操作。

5.2 使用 Mockito 创建模拟对象

Mockito 是一个流行的模拟框架,可以轻松创建模拟对象。首先,我们需要在项目中添加 Mockito 的依赖:

<!-- pom.xml 示例 -->
<dependency><groupId>org.mockito</groupId><artifactId>mockito-core</artifactId><scope>test</scope>
</dependency>

接着,我们可以使用 @Mock 注解来创建模拟对象,并使用 @InjectMocks 来注入模拟对象到被测类。

package com.example.demo;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 static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;@SpringBootTest
class HelloWorldServiceTest {@Mockprivate SomeDependency someDependency;@InjectMocksprivate HelloWorldService helloWorldService;@BeforeEachpublic void setUp() {MockitoAnnotations.openMocks(this);}@Testvoid shouldReturnDefaultMessage() {// 给定String name = "Alice";when(someDependency.getName()).thenReturn(name);// 当String result = helloWorldService.sayHello(someDependency.getName());// 然后assertEquals("Hello Alice!", result);}
}

在这个例子中,SomeDependency 是一个假设存在的依赖类,它有一个 getName() 方法。我们使用 Mockito 创建了一个模拟的 SomeDependency 对象,并且配置它在 getName() 被调用时返回 "Alice"

5.3 注入模拟对象到被测类

使用 @InjectMocks 注解,Spring 将自动将模拟对象注入到 HelloWorldService 实例中。这样,当 sayHello 方法调用 someDependency.getName() 时,实际上调用的是模拟对象的方法,并且返回我们预先配置好的值。

5.4 测试依赖注入

当我们使用 @SpringBootTest 注解时,Spring Boot 会创建一个完整的 Spring 应用上下文,并自动注入所有被标注为 @Component 或其子注解的 Bean。在单元测试中,我们通常想要避免这种情况,因为完整的上下文会带来额外的开销,并且可能引入不必要的复杂性。因此,我们可以使用 @RunWith(SpringRunner.class) 来启动一个 Spring 测试运行器,或者使用 @ContextConfiguration 显式指定要加载的配置类。

5.5 验证方法调用

除了验证返回值之外,我们还经常需要验证某个方法是否被正确调用。Mockito 提供了 verify 方法来实现这一点。

@Test
void shouldCallDependencyMethod() {// 给定String name = "Alice";when(someDependency.getName()).thenReturn(name);// 当helloWorldService.sayHello(someDependency.getName());// 然后verify(someDependency).getName();
}

在这个测试中,我们首先配置 getName() 方法的返回值,然后调用 sayHello 方法,最后使用 verify 方法来确认 getName() 是否被调用过。


6. 集成测试和端到端测试

6.1 集成测试 vs 单元测试

单元测试关注的是单个方法或组件的行为,确保每个部分都能按预期工作。单元测试通常不涉及外部系统或服务,而是通过模拟对象来隔离外部依赖。

集成测试则关注多个组件之间的交互,验证不同组件组合在一起时能否正确协同工作。集成测试可能会涉及到数据库访问、网络请求等外部系统,因此比单元测试更为复杂,执行速度也较慢。

6.2 使用 Spring Boot 进行集成测试

Spring Boot 提供了多种方式进行集成测试。一种常见的方法是使用 @DataJpaTest@WebMvcTest 注解,它们分别用于测试数据访问层和 Web 控制器。

示例:使用 @DataJpaTest 进行集成测试

package com.example.demo;import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;import javax.persistence.EntityManager;import static org.assertj.core.api.Assertions.assertThat;@DataJpaTest
public class UserRepositoryIntegrationTest {@Autowiredprivate UserRepository userRepository;@Autowiredprivate EntityManager entityManager;@Testvoid shouldFindUserById() {// 给定User user = new User("Alice", "alice@example.com");entityManager.persist(user);entityManager.flush();// 当User foundUser = userRepository.findById(user.getId()).orElse(null);// 然后assertThat(foundUser).isNotNull();assertThat(foundUser.getUsername()).isEqualTo(user.getUsername());assertThat(foundUser.getEmail()).isEqualTo(user.getEmail());}
}

示例:使用 @WebMvcTest 进行集成测试

package com.example.demo;import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;@WebMvcTest(controllers = GreetingController.class)
public class GreetingControllerIntegrationTest {@Autowiredprivate MockMvc mockMvc;@Testvoid shouldReturnGreeting() throws Exception {mockMvc.perform(get("/greeting")).andExpect(status().isOk()).andExpect(content().string("Hello World!"));}
}

6.3 端到端测试简介

端到端测试(E2E 测试)是从用户的角度出发,测试整个应用程序的工作流程。E2E 测试通常涉及浏览器自动化工具(如 Selenium)或 API 测试工具(如 Postman)。

在 Spring Boot 中,可以使用 Spring Boot 的 @SpringBootTest 注解配合 MockMvcTestRestTemplate 来执行 E2E 测试。

6.4 Web 测试支持 (Spring MVC Test)

Spring Boot 提供了 MockMvc 来测试 Web 层,它允许开发者模拟 HTTP 请求并验证响应。下面是一个简单的示例:

package com.example.demo;import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;@WebMvcTest(controllers = GreetingController.class)
public class GreetingControllerWebTest {@Autowiredprivate MockMvc mockMvc;@Testvoid shouldReturnGreeting() throws Exception {mockMvc.perform(get("/greeting")).andExpect(status().isOk()).andExpect(content().string("Hello World!"));}
}

7. 高级主题

7.1 异常处理测试

测试异常处理是为了确保当出现错误情况时,应用程序能够正确地处理这些异常,并向用户返回合适的错误信息。

示例:

package com.example.demo;import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;@WebMvcTest(controllers = GreetingController.class)
public class GreetingControllerExceptionHandlingTest {@Autowiredprivate MockMvc mockMvc;@Testvoid shouldHandleException() throws Exception {mockMvc.perform(get("/greeting/error")).andExpect(status().isBadRequest());}
}

7.2 异步操作测试

异步操作测试需要特别注意,因为它们涉及到非阻塞的操作。可以使用 CountDownLatch 或者 Awaitility 库来等待异步操作完成。

示例:

package com.example.demo;import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.concurrent.TimeUnit;import static org.junit.jupiter.api.Assertions.assertEquals;@SpringBootTest
public class AsyncServiceTest {@Autowiredprivate AsyncService asyncService;@Testvoid shouldProcessAsync() {asyncService.processAsync("Alice");Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() -> asyncService.getResult().equals("Processed Alice"));}
}

7.3 测试数据库交互

为了测试数据库交互,可以使用内存数据库(如 H2)或事务隔离测试(通过 @Transactional 注解)来确保测试之间相互独立。

示例:

package com.example.demo;import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.transaction.annotation.Transactional;import static org.assertj.core.api.Assertions.assertThat;@DataJpaTest
@Transactional
public class UserRepositoryDatabaseTest {@Autowiredprivate UserRepository userRepository;@Testvoid shouldSaveAndLoadUser() {User user = new User("Alice", "alice@example.com");userRepository.save(user);User foundUser = userRepository.findById(user.getId()).orElse(null);assertThat(foundUser).isNotNull();assertThat(foundUser.getUsername()).isEqualTo(user.getUsername());assertThat(foundUser.getEmail()).isEqualTo(user.getEmail());}
}

7.4 性能测试

性能测试是为了确保应用程序能够在高负载下仍能保持良好的响应时间和吞吐量。可以使用 JMeter 或 Gatling 等工具来进行性能测试。

7.5 并行测试执行

为了加速测试执行,可以使用并行测试执行。Spring Boot 支持通过 JUnit 5 的 @ExtendWith(SpringExtension.class)ParallelExecutionConfiguration 来实现并行测试。

示例:

package com.example.demo;import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.ExecutionMode;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;@ExtendWith(SpringExtension.class)
@Execution(ExecutionMode.CONCURRENT)
@SpringBootTest
public class ParallelTestsExample {@Testvoid testOne() {// 测试逻辑}@Testvoid testTwo() {// 测试逻辑}
}

8. 最佳实践和技巧

保持测试独立性

每个测试都应该独立于其他测试运行,避免测试之间的相互依赖。使用 @BeforeEach@AfterEach 来设置和清理测试环境。

重构和维护测试代码

就像生产代码一样,测试代码也需要定期重构以保持清晰和可维护。遵循 SOLID 原则,并确保测试代码具有良好的组织结构。

测试覆盖率

使用代码覆盖率工具(如 JaCoCo)来监控测试覆盖率,并确保重要逻辑路径都得到了覆盖。

使用 CI/CD 管道自动化测试

持续集成(CI)和持续部署(CD)管道可以自动运行测试,确保每次提交代码时都能及时发现问题。

常见陷阱和解决方案

  • 过度依赖外部系统:尽量使用模拟对象或存根来替代外部依赖。
  • 忽视异常处理:确保所有的异常处理逻辑都被充分测试。
  • 测试代码冗余:避免重复代码,可以将公共测试逻辑提取到基类或共享方法中。

9. 总结与展望

本篇文章要点回顾

  • 我们从单元测试的基础知识讲起,介绍了 Spring Boot 中单元测试的重要性和基本概念。
  • 展示了如何创建 Spring Boot 项目并设置测试环境。
  • 通过示例展示了如何编写和运行单元测试。
  • 探讨了模拟对象和依赖注入的测试方法。
  • 解释了集成测试和端到端测试的区别,并提供了相应的示例。
  • 讨论了高级测试主题,如异常处理、异步操作、数据库交互、性能测试和并行测试执行。
  • 提出了测试的最佳实践和技巧。

单元测试在软件开发中的价值

单元测试是软件开发不可或缺的一部分,它有助于早期发现缺陷、提高代码质量和重构的安全性。通过自动化测试,可以显著减少手动测试的时间和成本。

未来趋势和技术发展

随着技术的发展,测试工具和框架也在不断进步。未来可能会看到更多智能测试工具的出现,这些工具能够自动识别测试用例并优化测试执行。

这篇关于【全面解析】Spring Boot 中的单元测试:从基础到实战的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1125890

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置