Java学习,一文掌握Java之SpringBoot框架学习文集(2)

news2024/11/15 4:56:41

在这里插入图片描述

🏆作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。
🏆多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。
🎉欢迎 👍点赞✍评论⭐收藏

SpringBoot知识专栏学习

SpringBoot知识云集访问地址备注
SpringBoot知识点(1)https://blog.csdn.net/m0_50308467/article/details/135322153SpringBoot专栏
SpringBoot知识点(2)https://blog.csdn.net/m0_50308467/article/details/135323253SpringBoot专栏

文章目录

  • 🏆 学习Java框架之Spring Boot
    • 🔎 Java框架之Spring Boot学习(2)
      • 🍁🍁 01、如何在 Spring Boot 中集成日志系统?
      • 🍁🍁 02、如何配置多个数据源?
      • 🍁🍁 03、Spring Boot 提供了哪些方式用于数据库的访问?
      • 🍁🍁 04、Spring Boot 如何处理请求参数的校验?
      • 🍁🍁 05、如何在 Spring Boot 中处理异常?
      • 🍁🍁 06、Spring Boot 中的 AOP 是如何实现的?
      • 🍁🍁 07、如何在 Spring Boot 中集成缓存?
      • 🍁🍁 08、Spring Boot 的测试方式有哪些?
      • 🍁🍁 09、如何在 Spring Boot 中使用消息队列?
      • 🍁🍁 10、Spring Boot 中的微服务架构是怎样实现的?

🏆 学习Java框架之Spring Boot

🔎 Java框架之Spring Boot学习(2)

🍁🍁 01、如何在 Spring Boot 中集成日志系统?

在 Spring Boot 中,集成日志系统一般有两种方式:使用 Spring Boot 默认的日志框架或集成其他日志框架。

1. 使用 Spring Boot 默认的日志框架

Spring Boot 默认使用 Logback 作为日志框架,不需要进行任何配置。只需在类路径下添加 logback.xml 或者 logback-spring.xml,Logback 就会自动加载相应的配置文件,并输出日志。

以下是一个 logback.xml 日志配置实例,通过配置可以将日志分为控制台输出和文件输出两部分,支持日志级别、日志滚动等基本功能。示例代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 定义控制台输出日志 -->
	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
		<encoder charset="UTF-8">
			<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
		</encoder>
	</appender>
	<!-- 定义文件输出日志 -->
	<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
		<!-- 文件输出路径 -->
		<file>logs/application.log</file>
		<!-- 文件滚动方式 -->
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<!-- 文件滚动周期 -->
			<fileNamePattern>logs/application.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
			<!-- 文件最大历史记录 -->
			<maxHistory>30</maxHistory>
			<!-- 最大文件大小 -->
			<maxFileSize>10MB</maxFileSize>
		</rollingPolicy>
		<encoder charset="UTF-8">
			<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
		</encoder>
	</appender>
	<!-- root 日志记录器 -->
	<root level="info">
		<appender-ref ref="console" />
		<appender-ref ref="file" />
	</root>
</configuration>

其中,<appender> 标签用于定义一个日志输出目的地,包括控制台输出和文件输出两个部分,分别用 ConsoleAppenderRollingFileAppender 实现。<root> 标签用于定义日志记录器的根节点,包括输出日志级别和选择的 Appender。

在日志配置文件中,还可以定义自己的日志级别、自定义输出格式和输出目的地等,根据具体需求进行配置。

2. 集成其他日志框架

Spring Boot 同时支持集成其他日志框架,如 log4jlog4j2slf4j 等。以集成 Log4j2 为例,需要执行以下步骤:

2.1 添加 Log4j2 依赖

pom.xml 文件中,添加以下依赖:

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

2.2 配置 Log4j2

在类路径下创建 log4j2.xml 或者 log4j2-spring.xml 配置文件,对 Log4j2 进行配置。可以配置输出的日志级别、日志输出格式和输出目的地等信息。

2.3 修改 Spring Boot 的默认日志框架

application.properties 或者 application.yml 文件中,将 Spring Boot 默认的日志框架修改为 Log4j2:

application.properties

# 修改 Spring Boot 的默认日志框架为 Log4j2
logging.config=classpath:log4j2.xml

application.yml

# 修改 Spring Boot 的默认日志框架为 Log4j2
logging:
  config: classpath:log4j2.yml

通过以上步骤,就可以将 Log4j2 集成到 Spring Boot 中,并使用 Log4j2 输出日志。

总的来说,在 Spring Boot 中集成日志系统非常简单,开发者只需要少量的配置和几个依赖,就可以轻松完成日志集成。

🍁🍁 02、如何配置多个数据源?

在 Spring Boot 中配置多个数据源可以通过以下步骤完成:

1. 定义数据源配置

application.properties 或者 application.yml 中定义多个数据源的配置信息。例如,假设我们需要配置两个数据源,分别为 datasource1datasource2,可以进行如下配置:

application.properties

# 数据源1配置
spring.datasource.datasource1.url=jdbc:mysql://localhost:3306/datasource1
spring.datasource.datasource1.username=root
spring.datasource.datasource1.password=password
spring.datasource.datasource1.driver-class-name=com.mysql.jdbc.Driver

# 数据源2配置
spring.datasource.datasource2.url=jdbc:mysql://localhost:3306/datasource2
spring.datasource.datasource2.username=root
spring.datasource.datasource2.password=password
spring.datasource.datasource2.driver-class-name=com.mysql.jdbc.Driver

application.yml

# 数据源1配置
spring:
  datasource:
    datasource1:
      url: jdbc:mysql://localhost:3306/datasource1
      username: root
      password: password
      driver-class-name: com.mysql.jdbc.Driver

# 数据源2配置
spring:
  datasource:
    datasource2:
      url: jdbc:mysql://localhost:3306/datasource2
      username: root
      password: password
      driver-class-name: com.mysql.jdbc.Driver

2. 创建多个数据源实例

创建多个数据源实例,并将其注入到 Spring Boot 中。可以使用 @ConfigurationProperties 注解将配置文件中的数据源配置注入到对应的数据源实例中。

@Configuration
public class DataSourceConfig {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.datasource1")
    public DataSource dataSource1() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.datasource2")
    public DataSource dataSource2() {
        return DataSourceBuilder.create().build();
    }
}

3. 使用多个数据源

在需要使用数据源的地方通过 @Qualifier 注解来指定具体使用哪个数据源。

@Service
public class SomeService {

    @Autowired
    @Qualifier("dataSource1") // 使用 dataSource1 数据源
    private DataSource dataSource1;

    @Autowired
    @Qualifier("dataSource2") // 使用 dataSource2 数据源
    private DataSource dataSource2;

    // ...
}

通过以上步骤,就可以成功配置多个数据源并在应用程序中使用它们。需要注意的是,Spring Boot 默认使用的数据源是配置文件中 spring.datasource.* 的配置,如果需要使用其他数据源,需通过 @Qualifier 明确指定。

🍁🍁 03、Spring Boot 提供了哪些方式用于数据库的访问?

Spring Boot 提供了以下几种方式用于数据库的访问:

  1. JDBC:Spring Boot 提供了对 JDBC 的支持,可以通过 JDBC 连接各种关系型数据库。可以使用 JdbcTemplate 或 NamedParameterJdbcTemplate 执行 SQL 查询和更新操作。

  2. JPA(Java Persistence API):Spring Boot 集成了 JPA,可以使用 JPA 来访问关系型数据库。通过定义实体类和仓库接口,可以自动生成 SQL 语句并进行 CRUD(Create、Read、Update、Delete)操作。

  3. MyBatis:Spring Boot 支持 MyBatis 持久化框架,可以使用 MyBatis 提供的注解或 XML 配置来编写 SQL 映射文件,实现与关系型数据库的交互。

  4. Spring Data JPA:Spring Boot 还集成了 Spring Data JPA,它是 Spring Data 技术栈中的一部分,用于简化 JPA 的使用。通过定义仓库接口继承自 JpaRepository,可以实现基本的 CRUD 操作,还支持基于方法名、@Query 注解等方式进行自定义查询。

  5. NoSQL 数据库:除了关系型数据库,Spring Boot 还支持一些 NoSQL 数据库,如 MongoDB、Redis、Elasticsearch 等。可以使用相应的驱动或客户端库来与这些数据库进行交互。

这些方式各有优劣,具体使用哪种方式取决于应用的需求和个人偏好。最适合的方式取决于数据访问场景,例如如果需要频繁进行复杂查询和关联查询,JPA 可能更适合;如果需要更灵活的 SQL 控制和性能优化,可以选择 MyBatis;如果需要简化 CRUD 操作,可以使用 Spring Data JPA。

🍁🍁 04、Spring Boot 如何处理请求参数的校验?

Spring Boot 中可以使用 JSR 303 Bean Validation 标准来进行请求参数的校验。具体来说,需要在请求参数所属的类上添加注解来指定校验规则,然后在 Controller 层上通过 @Valid 注解来触发校验,并使用 BindingResult 对象来获取校验结果。

以下是一个示例:

@RestController
public class UserController {

   @PostMapping("/users")
   public ResponseEntity createUser(@Valid @RequestBody UserDto userDto, BindingResult result) {
       if (result.hasErrors()) {
           List<String> errors = result.getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage)
                   .collect(Collectors.toList());
           return ResponseEntity.badRequest().body(errors);
       }
       // 执行创建用户的操作
       return ResponseEntity.ok("User created successfully.");
   }
}

在上述示例中,UserDto 类上添加了校验规则,比如使用 @NotBlank 注解来指定某个字段不能为空。在 createUser 方法上,使用 @Valid 注解来触发校验,并在方法参数中添加 BindingResult 参数,用于存储校验结果。如果校验结果有错误,则可以通过 result 对象获取错误信息并返回给客户端。

需要注意的是,如果需要在出现校验错误时直接返回错误信息,可以使用 @ControllerAdvice注解定义全局的异常处理器来处理 MethodArgumentNotValidException 异常,这样就可以在出现校验错误时直接返回提示信息,而不是抛出异常。

除了使用 JSR 303 Bean Validation 进行请求参数的校验,Spring Boot 还提供了其他的参数校验方式:

  1. 使用注解:除了 JSR 303 注解外,还可以使用其他自定义的注解来对请求参数进行校验。可以自定义注解,并在相应的请求参数上添加该注解,并编写校验逻辑。

  2. 使用 Validator:可以自定义 Validator 来对请求参数进行校验。需要实现 org.springframework.validation.Validator 接口,并覆盖 supportsvalidate 方法。然后在 Controller 层使用 @InitBinder 注解注册该 Validator。

当在 Spring Boot 中需要对请求参数进行验证时,可以编写自定义的 Validator 来实现验证逻辑。下面是一个示例:

首先,你需要创建一个自定义的校验器类,该类需要实现 org.springframework.validation.Validator 接口。接下来,你可以在该类中实现校验逻辑。

import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

@Component
public class CustomValidator implements Validator {

    @Override
    public boolean supports(Class<?> clazz) {
        // 指定该校验器支持的目标类
        return CustomObject.class.equals(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        // 执行具体的校验逻辑
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "name.required", "Name is required");
        
        CustomObject customObject = (CustomObject) target;
        
        if (customObject.getAge() < 0) {
            errors.rejectValue("age", "age.invalid", "Age must be a positive number");
        }
    }
}

在上面的示例中,我们创建了一个名为 CustomValidator 的自定义校验器。在校验器中,我们通过实现 supports 方法指定该校验器支持的目标类(这里是 CustomObject 类),并实现 validate 方法执行具体的校验逻辑。

validate 方法中,我们使用 ValidationUtils.rejectIfEmptyOrWhitespace 方法校验 name 属性是否为空或仅包含空格,并注册一个错误(如果校验失败)。然后,我们手动检查 age 属性是否小于零,并通过 errors.rejectValue 方法注册一个错误(如果校验失败)。

请注意,在示例中,我们使用了 @Component 注解将自定义校验器声明为 Spring Bean,并且自动扫描和注入到 Spring Boot 应用程序中。

接下来,你可以在控制器类中使用该自定义校验器了。例如:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {
    
    @Autowired
    private CustomValidator customValidator;
    
    @PostMapping("/data")
    public String processData(@RequestBody CustomObject customObject, BindingResult bindingResult) {
        customValidator.validate(customObject, bindingResult);
        
        if (bindingResult.hasErrors()) {
            // 处理校验错误
            return "Validation failed: " + bindingResult.toString();
        }
        
        // 校验通过,处理业务逻辑
        return "Data processed successfully";
    }
}

在上面的示例中,我们在控制器类中注入了自定义校验器,并在处理请求的方法中调用 customValidator.validate 方法进行校验。然后,我们可以检查 BindingResult 对象中是否有错误,并根据需要做一些处理。

无论使用哪种方式进行参数校验,都需要在 Controller 层进行触发配合并处理校验结果,可以根据具体的需求选择合适的方式。

🍁🍁 05、如何在 Spring Boot 中处理异常?

在 Spring Boot 应用中,可以使用 Spring 提供的异常处理机制来捕获和处理异常。Spring Boot 允许通过 @ExceptionHandler 注解定义异常处理方法,用于捕获和处理控制器中抛出的异常。具体实现方法如下:

1. 定义异常处理类

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.clss)
    public ResponseEntity handleException(Exception ex) {
        //处理异常
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ex.getMessage());
    }
}

GlobalExceptionHandler 类中使用了 @ControllerAdvice 注解声明该类为全局异常处理类。然后使用 @ExceptionHandler 注解来定义处理异常的方法。在示例中,我们定义了一个处理 Exception 类型异常的方法 handleException(),当系统抛出 Exception 类型的异常时,会自动调用该方法进行异常处理。

2. 抛出异常

在控制器类中,可以通过 throw new Exception() 的方式手动抛出一个异常。这个异常将会被 GlobalExceptionHandler 中定义的异常处理方法所捕获并进行处理。

@RestController
public class UserController {

    @GetMapping("/users")
    public List<User> getAllUsers() {
        if (true) {
            throw new Exception("Something wrong.");
        }
        return userRepository.findAll();
    }
}

在上述示例中,getAllUsers() 方法中通过 throw new Exception() 的方式手动抛出一个异常,当这个异常发生时,GlobalExceptionHandler 中定义的异常处理方法会自动进行处理,并返回错误信息。

值得注意的是,@ControllerAdvice 注解中还可以指定处理的异常类型,比如 @ControllerAdvice(basePackages = {"com.example.controller"}) 就只处理 com.example.controller 包下抛出的异常。

另外,Spring Boot 也提供了默认的异常处理机制,部分常见异常会自动被 Spring Boot 捕捉并进行处理,比如 400 Bad Request404 Not Found500 Internal Server Error 等。但是我们也可以自定义处理这些异常的方式,只需要定义对应异常类型的处理方法即可。

3. 统一返回异常信息

在实际应用中,为了使代码具备良好的可维护性和可读性,同时也为了前端开发人员和其他调用方能够更好地理解异常信息,通常需要在异常处理方法中将异常信息封装成一个统一的数据格式并返回,比如通常返回一个包含错误码和错误信息的 JSON 对象。

为了实现这个功能,可以使用 Spring Boot 异常处理机制中的 @ControllerAdvice@ExceptionHandler 注解,代码示例如下:

@ControllerAdvice
public class GlobalExceptionHandler {

    // 处理所有的 Controller 层抛出的 Exception 异常
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ResponseResult handleException(Exception ex) {
        // 统一封装异常信息
        return ResponseResult.failure(ex.getMessage());
    }

    // 处理特定的异常
    @ExceptionHandler(ArithmeticException.class)
    @ResponseBody
    public ResponseResult handleArithmeticException(ArithmeticException ex) {
        // 统一封装异常信息
        return ResponseResult.failure("运算异常:" + ex.getMessage());
    }
}

在上述代码中,我们定义了两个异常处理方法handleException()handleArithmeticException(),使用了 @ExceptionHandler 注解来指定处理的异常类型,并使用 @ResponseBody 注解将返回结果封装成 JSON 对象。

当系统中抛出异常时,会根据异常类型匹配对应的异常处理方法,进行异常信息的统一处理和格式化返回。这样可以统一前端的数据格式,避免每个接口都需要单独处理异常返回信息的问题。

总的来说,Spring Boot 异常处理机制非常强大,可灵活应用于各种场景中。通过合理使用 @ExceptionHandler@ControllerAdvice@ResponseBody等注解,我们可以更加优雅和高效地处理异常,并实现统一的异常信息返回。

🍁🍁 06、Spring Boot 中的 AOP 是如何实现的?

在 Spring Boot 中,AOP(面向切面编程)是通过使用 Spring Framework 的 AOP 模块实现的。AOP 可以帮助开发者将与业务逻辑无关的横切关注点(例如日志记录、事务管理、权限控制等)从应用程序的主线程中分离出来,提供了更好的代码模块化、可维护性和可读性。

要使用 AOP 功能,需要进行以下几个步骤:

  1. 添加依赖:在 pom.xml 文件中添加 Spring AOP 的依赖。

  2. 定义切面:创建一个切面类,使用 @Aspect 注解进行标识,同时在切面类中定义切入点(@Pointcut 注解)和通知(@Before@After@Around 等注解)。

  3. 配置代理:在 Spring Boot 配置类中使用 @EnableAspectJAutoProxy 注解来启用自动代理功能,从而实现 AOP。

下面是一个简单的示例代码,展示了如何在 Spring Boot 中使用 AOP:

// 定义切面类
@Aspect
@Component
public class LoggingAspect {

    @Before("execution(* com.example.demo.service.*.*(..))")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("Before method: " + joinPoint.getSignature().getName());
    }
}

// 配置类
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
}

在上述代码中,我们创建了一个切面类 LoggingAspect,使用 @Aspect 注解进行标识,并定义了一个前置通知方法 logBefore()。该方法使用了 @Before 注解,并通过 execution(* com.example.demo.service.*.*(..)) 定义了切入点表达式,表示在所有 com.example.demo.service 包下的类的所有方法执行前都会执行该通知方法。

另外需要注意的是,在配置类 AppConfig 中,我们使用 @EnableAspectJAutoProxy 注解来启用自动代理功能,从而使得 AOP 功能生效。

需要注意的是,上述示例代码仅是一个简单的示例,实际项目中可能会更复杂。切入点表达式可以根据实际需要进行定制,通知方法可以根据需要选择不同的注解,例如 @Before@After@Around 等。

总结来说,Spring Boot 中的 AOP 是通过使用 Spring Framework 的 AOP 模块实现的。通过定义切面类、切入点和通知,并启用自动代理功能,可以实现对应用程序的横切关注点进行统一管理和处理。

下面给出一个更具体的示例来说明每个步骤。假设我们有一个简单的应用程序,其中包含一个服务类 UserService,它提供了一个方法 getUserById() 来获取用户信息。

1. 添加依赖:在项目的 pom.xml 文件中添加如下所示的 Spring AOP 依赖:

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

2. 定义切面:创建一个切面类 LoggingAspect,使用 @Aspect 注解进行标识,并在其中定义一个前置通知方法 logBefore()

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {

    @Before("execution(* com.example.demo.service.UserService.getUserById(..))")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("Before method: " + joinPoint.getSignature().getName());
    }
}

在上述代码中,我们使用 @Before 注解标识了一个前置通知方法 logBefore(),并使用 execution(* com.example.demo.service.UserService.getUserById(..)) 表达式定义了切入点,表示在调用 UserService 类中的 getUserById() 方法前执行该通知方法。

3. 配置代理:创建一个配置类 AppConfig,使用 @Configuration@EnableAspectJAutoProxy 注解来启用自动代理功能。

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
}

在上述代码中,我们使用 @EnableAspectJAutoProxy 注解启用自动代理,在使用 @Configuration 注解标识的配置类中,Spring Boot 会自动代理标记了 @Aspect 注解的切面类。

通过以上三个步骤,我们就完成了在 Spring Boot 中使用 AOP 的配置和基本示例。

当我们调用 UserService 类的 getUserById() 方法时,AOP 切面会在方法执行前打印一条日志。这可以帮助我们更好地理解 AOP 在 Spring Boot 中的具体应用。

注意:为了让以上示例代码能够正确运行,还需要确保 UserService 类和 AppConfig 配置类位于正确的包路径下,并且在启动类中包含了正确的组件扫描配置,以确保切面类和服务类被正确初始化和代理。

🍁🍁 07、如何在 Spring Boot 中集成缓存?

在 Spring Boot 中集成缓存可以通过以下步骤实现:

1. 添加依赖:在项目的 pom.xml 文件中添加与缓存相关的依赖。常用的缓存依赖有 spring-boot-starter-cachespring-boot-starter-data-redis(如果使用 Redis 缓存)。例如,如果你要使用 Spring Cache,可以添加以下依赖:

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

2. 配置缓存配置类:创建一个配置类,用于配置缓存。你可以使用 @EnableCaching 注解来启用缓存功能,并使用 @Configuration 注解标记该类为配置类。示例如下:

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableCaching
public class CacheConfig {
}

3. 配置缓存管理器:根据你选择的缓存技术,配置相应的缓存管理器。如果你选择使用 Spring Cache,默认情况下会使用 ConcurrentMapCacheManager 作为缓存管理器。如果你要使用 Redis 缓存,可以配置 RedisCacheManager。示例如下:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;

@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        RedisSerializer<Object> serializer = new GenericJackson2JsonRedisSerializer();
        template.setDefaultSerializer(serializer);
        return template;
    }

    @Bean
    public RedisCacheManager cacheManager(RedisTemplate<String, Object> redisTemplate) {
        RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager.builder(redisTemplate.getConnectionFactory())
                .cacheDefaults(cacheConfiguration)
                .build();
        return cacheManager;
    }
}

上述代码中的 redisTemplate() 方法配置了 RedisTemplate,使用 Jackson 序列化对象,并设置为默认序列化器。cacheManager() 方法配置了 RedisCacheManager,并设置了缓存配置。

4. 在方法上添加缓存注解:在想要缓存的方法上,使用 Spring Cache 提供的缓存注解来标记方法的返回结果应该被缓存。常用的缓存注解有 @Cacheable@CachePut@CacheEvict。示例如下:

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Cacheable("users")
    public User getUserById(Long userId) {
        // 从数据库或其他数据源获取用户信息
        // ...
    }
}

上述代码中的 @Cacheable("users") 注解表示该方法的返回结果将被缓存,并使用名为 “users” 的缓存区域。

通过以上步骤,你就可以在 Spring Boot 中集成缓存了。请确保缓存配置类和服务类位于正确的包路径下,并在启动类中包含了正确的组件扫描配置,以确保缓存功能正常运行。

🍁🍁 08、Spring Boot 的测试方式有哪些?

Spring Boot 提供了多种方式来进行测试,其中包括:

  1. 单元测试(Unit Testing):针对应用中的单个类或方法进行测试,通常使用 JUnit 或者其他单元测试框架来完成。可以使用 Mockito、EasyMock 等工具进行依赖注入和模拟对象。
  2. 集成测试(Integration Testing):用于测试各个组件之间的集成行为,比如测试数据库访问、HTTP 请求、消息队列等。可以使用 Spring 的 TestRestTemplate、MockMvc 等工具进行测试。
  3. 自动化功能测试(Automated Functional Testing):通过模拟用户的实际操作来测试应用的功能。可以使用 Selenium、Robot Framework 等工具进行自动化测试。
  4. 端到端测试(End-to-End Testing):测试整个应用的流程,从用户界面开始到数据存储层结束。可以使用 Cucumber、JBehave 等工具进行测试。
  5. 性能测试(Performance Testing):用于测试应用在不同负载下的性能和稳定性。可以使用 Apache JMeter、Gatling 等工具进行性能测试。
  6. 安全测试(Security Testing):用于测试应用的安全性漏洞,如跨站脚本攻击、SQL 注入等。可以使用 OWASP ZAP、Burp Suite 等工具进行安全测试。
  7. 接口测试(API Testing):针对应用提供的接口进行测试,验证接口的输入输出是否符合预期。可以使用 Postman、RestAssured 等工具进行接口测试。
  8. UI 测试(UI Testing):测试应用的用户界面是否正常工作,包括检查页面布局、用户交互等。可以使用 Selenium WebDriver、Cypress 等工具进行 UI 测试。
  9. 数据库测试(Database Testing):测试应用与数据库的交互是否正确,包括数据的插入、更新、查询等。可以使用 H2、DbUnit 等工具进行数据库测试。
  10. 日志测试(Logging Testing):测试应用是否正确地生成和记录日志,以及日志的格式、级别等是否符合预期。可以使用 Logback、Log4j 等工具进行日志测试。
  11. 异常测试(Exception Testing):测试应用在不同输入条件下是否正确地处理异常情况,比如抛出正确的异常、进行适当的错误处理等。
  12. 集成第三方服务的测试:如果应用依赖于其他第三方服务,可以进行测试来验证与这些服务的集成是否正常工作。

通过综合使用上述测试方式,可以全面覆盖 Spring Boot 应用的各个方面,确保应用的功能、性能、安全性等都得到验证和保证。根据具体需求,可以选择适当的测试方式或者组合多种测试方式进行测试。

🍁🍁 09、如何在 Spring Boot 中使用消息队列?

在 Spring Boot 中使用消息队列的过程主要分为两部分:集成消息队列和使用消息队列。Spring Boot 支持多种消息队列系统,包括 ActiveMQ、RabbitMQ、Kafka 等,这里以 RabbitMQ 为例进行说明。

集成 RabbitMQ 的步骤如下

1. 添加依赖

在 pom.xml 文件中添加 RabbitMQ 的依赖:

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

2. 配置 RabbitMQ

在 application.properties 文件中添加 RabbitMQ 的配置:

spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

这里假设 RabbitMQ 在本地运行,默认端口为 5672,用户名和密码为 guest。

使用 RabbitMQ的例子:

下面是一个简单的例子,展示如何使用 RabbitMQ 发送和接收消息。

1. 设置消息队列

@Configuration
public class RabbitMQConfig {

    public static final String QUEUE_NAME = "example-queue";

    @Bean
    public Queue queue() {
        return new Queue(QUEUE_NAME);
    }

}

这里使用了 @Configuration 注解,将该类作为配置类,配置了一个名为 example-queue 的队列。

2. 发送消息

@Service
public class MessageSender {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void sendMessage(String message) {
        rabbitTemplate.convertAndSend(RabbitMQConfig.QUEUE_NAME, message);
    }

}

可以使用 RabbitTemplate 的 convertAndSend 方法发送消息。

3. 接收消息

@Component
public class MessageReceiver {

    @RabbitListener(queues = RabbitMQConfig.QUEUE_NAME)
    public void handleMessage(String message) {
        System.out.println("Received message: " + message);
    }

}

使用 @RabbitListener 注解标注一个方法,表示该方法监听名为 example-queue 的队列,当队列中有消息时,该方法会自动被调用。这里的方法名可以自定义,方法参数的类型也可以自定义。

这里的代码片段演示了如何使用 RabbitMQ 发送和接收简单的文本消息。在实际应用中,可能需要处理更复杂的消息类型,比如对象、二进制数据等。Spring Boot 提供了多种序列化方式来支持这些消息类型,可以使用 Jackson、Protobuf 等工具进行序列化和反序列化,并在队列配置类中进行相应的配置。

🍁🍁 10、Spring Boot 中的微服务架构是怎样实现的?

在 Spring Boot 中实现微服务架构的关键在于以下几个方面:

1. 服务拆分:将一个大型的单体应用拆分成多个小而自治的服务。每个服务只关注自己的业务逻辑,独立开发、构建和部署。可以根据领域驱动设计(Domain-driven Design, DDD)的原则来进行服务的拆分。

2. 服务注册与发现:使用服务注册与发现机制来管理各个微服务的信息。常见的实现方式是通过使用类似于 Netflix Eureka 或者 Consul 这样的服务注册中心来实现,微服务在启动时将自己的信息注册到注册中心,其他微服务可以通过注册中心来获取服务的地址和信息。

3. 服务间通信:微服务需要通过网络进行通信。常见的通信方式包括 HTTP/REST、消息队列、RPC 等。可以使用 Spring Boot 提供的 RestTemplate、Feign、RabbitMQ、Apache Kafka、gRPC 等组件来实现服务间的通信。

4. 负载均衡:由于每个微服务都有多个实例在运行,需要实现负载均衡来分配请求到不同的实例上。可以使用负载均衡组件如 Nginx、Ribbon 或者使用服务注册中心提供的负载均衡功能。

5. 容错机制:微服务架构需要考虑容错处理,以处理服务的故障和异常情况。可以使用断路器(Circuit Breaker)实现服务的降级和熔断,常见的断路器实现有 Netflix Hystrix 和 Resilience4j。

6. 配置管理:微服务中的配置需要进行集中管理和动态刷新。可以使用配置中心组件如 Spring Cloud Config、Apollo 等来管理配置。

7. 集中式日志管理:微服务架构中需要统一管理日志,以便进行故障排查和监控。可以使用 ELK(Elasticsearch + Logstash + Kibana)等日志管理方案。

8. 安全认证与授权:对于需要安全访问的微服务,需要实现安全认证和授权。可以使用 Spring Security 和 JWT(JSON Web Token)等技术来进行实现。

这些是实现微服务架构的主要关键要点,在 Spring Boot 中,可以使用 Spring Cloud 提供的一系列组件来实现这些功能,如 Spring Cloud Netflix、Spring Cloud Ribbon、Spring Cloud Feign、Spring Cloud Config、Spring Cloud Sleuth 等。它们提供了对应的功能和集成途径,方便开发者构建和管理微服务架构。

当你已经在Spring Boot中构建了微服务架构后,以下是一些进一步的实践和技术,可以帮助你更好地管理和扩展微服务架构:

1. 服务网关:使用服务网关来提供统一的入口点,并处理微服务的路由、请求转发、过滤和认证等。常见的服务网关有 Spring Cloud Gateway 和 Netflix Zuul。

2. 分布式追踪与监控:在微服务架构中,一个请求往往会经过多个微服务的处理。分布式追踪技术可以帮助你跟踪一个请求在整个微服务系统中的处理流程,并进行性能监控和故障排查。你可以使用 Spring Cloud Sleuth 和 Zipkin 构建分布式追踪系统。

3. 自动化部署与容器化:为了更好地管理和扩展微服务,可以使用容器化技术,如 Docker 和 Kubernetes。这样可以实现快速部署、弹性伸缩和故障恢复等能力。

4. 服务治理:随着微服务数量的增加,服务的治理变得非常重要。可以使用服务注册中心、配置中心和断路器来进行服务的注册、配置管理和故障处理。同时,还可以使用服务网关来进行路由和流量控制。

5. 实时通信:在某些场景下,你可能需要实时的数据传输和通信。可以使用消息队列或者实时通信技术,如 WebSocket 来实现。Spring Cloud Stream 和 Apache Kafka 可以帮助你实现实时通信需求。

6. 数据管理:微服务架构中的数据管理也需要考虑。可以使用分布式数据库或者数据同步技术,如 Spring Data JPA、Spring Data MongoDB、Spring Cloud Data Flow 或者 Apache Kafka Connect 来管理和同步数据。

注意,以上提到的技术和实践都是一些辅助性的组件和策略,你可以根据具体需求来选择和应用。微服务架构的实现需要根据项目的规模、复杂度和业务需求进行灵活的调整和演进。

在这里插入图片描述

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

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

相关文章

LLVM(简介)

历史 LLVM(low level virtual machine)起源于伊利诺伊大学的一个编译器实验项目&#xff0c;目前已经发展成一个集编译器和工具链为一体的商业开源项目&#xff0c;因此其英文名称的含义被扩大&#xff0c;不再仅仅是字面意思。其创始人为 Chris Lattner。LLVM项目遵循的开源许…

流媒体学习之路(WebRTC)——Pacer与GCC(5)

流媒体学习之路(WebRTC)——Pacer与GCC&#xff08;5&#xff09; —— 我正在的github给大家开发一个用于做实验的项目 —— github.com/qw225967/Bifrost目标&#xff1a;可以让大家熟悉各类Qos能力、带宽估计能力&#xff0c;提供每个环节关键参数调节接口并实现一个json全…

单片机外设矩阵键盘之线反转法识别原理与示例

单片机外设矩阵键盘之线反转法识别原理与示例 1.概述 这篇文章主要介绍单片机接收 4X4矩阵键盘发出的指令&#xff0c;做出对应的反馈。其中主要介绍矩阵键盘线反转方式的识别原理和实操。 2.矩阵键盘线反转识别原理 2.1.矩阵键盘硬件接线原理 矩阵键盘的硬件接线方式有多种…

MySQL第三战:CRUD,函数1以及unionunion all

前言 在当今的数字化时代&#xff0c;数据库已经成为信息管理的重要工具。其中&#xff0c;MySQL作为一种流行的关系型数据库管理系统&#xff0c;已经广泛应用于各种业务场景。在本文中&#xff0c;我们将深入探讨MySQL中的核心概念&#xff0c;包括创建&#xff08;Create&a…

感恩客户相伴23载,泛微2024持续向上!

2023年&#xff0c;国家大力推动数字经济发展&#xff0c;各行各业在加速数字化转型&#xff0c;在这一年&#xff0c;泛微保持持续增长&#xff0c;引领行业发展&#xff0c;为组织的数字化转型助力。感恩客户与伙伴朋友的支持与信任&#xff01; 01.泛微中大客户总量突破8万余…

burpsuite模块介绍之extender(扩展)

extender Burp提供了对第三方拓展插件的支持,使用户能够编写自定义插件或从插件商店中安装拓展插件。这些Burp扩展程序可以以多种方式定制Burp的行为,包括修改HTTP请求和响应、自定义UI、添加自定义扫描程序检查以及访问关键的运行时信息,如代理历史记录、目标站点地图和扫…

Ubuntu Server 22.04 连接Wifi并配置静态IP

Ubuntu Server 22.04 连接Wifi并配置静态IP 前言&#xff1a;我家最近好几台电脑&#xff0c;我都想跑着Ubuntu Server做服务器&#xff0c;但是近几年的超级本已经不自带网口了&#xff0c;所以我就考虑用Wifi来联网&#xff0c;速度也还可以&#xff0c;但是既然是跑服务&…

工作中redis相关知识总结

这里写目录标题 一、Redis数据持久化概念二、redis数据类型三、redis缓存的应用流程四、什么样的数据适合存放到redis中&#xff1f;1、什么情况下&#xff0c;redis中会没有数据&#xff1f;2、redis缓存项目在测试中的注意事项a、更新缓存b、淘汰缓存 五、什么是缓存击穿1、缓…

【力扣题解】P236-二叉树的最近公共祖先-Java题解

&#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【力扣题解】 文章目录 【力扣题解】P236-二叉树的最近公共祖先-Java题解&#x1f30f;题目描述&#x1f4a1;题解&#x…

Vue.js 3.4版本发布:解析速度提升2倍,双向绑定革新等新功能

引言 随着2024年的来临,Vue团队的领军人物Evan You宣布了Vue.js 3.4的发布。这个版本不仅仅是修复了一些bug,还带来了一些非常实用的新功能和性能提升。 解析速度提升2倍 这次更新中,Vue.js 3.4实现了解析速度的大幅提升。尤其是在构建模板和脚本的源代码映射时,单文件组…

Python等高线图的绘制(Matplotlib篇-11)

Python等高线图的绘制(Matplotlib篇-11)         🍹博主 侯小啾 感谢您的支持与信赖。☀️ 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ…

k8s 之7大CNI 网络插件

一、介绍 网络架构是Kubernetes中较为复杂、让很多用户头疼的方面之一。Kubernetes网络模型本身对某些特定的网络功能有一定要求&#xff0c;但在实现方面也具有一定的灵活性。因此&#xff0c;业界已有不少不同的网络方案&#xff0c;来满足特定的环境和要求。 CNI意为容器网络…

Java基础-----集合类(三)

文章目录 1. Arraylist2. Arraylist常用方法 今天主要学习集合类框架 1. Arraylist Collection:是List和Set的父接口&#xff0c;里面包含了一些公用的方法 List:是一个有序的、不唯一的接口 ArrayList&#xff1a;是List的一个实现类&#xff0c;底层数据结构是数组 public…

终于学会听英文歌了:A Sad Me In Your Eyes

A Sad Me In Your Eyes 来源&#xff1a; https://lyricstranslate.com/en/ln-party-sad-me-your-eyes-lyrics.html Fire can’t burn in my eyes If without your smile Snow can cover your smile If without your love When you think of me, I’ve gone too far I can’t …

八怪:再谈 MySQL 8 这两个精准的时间戳

MySQL 8.0 的 binlog 中多了 immediate_commit_timestamp 和 original_commit_timestamp 的信息&#xff0c;网上也有很多文章进行解释&#xff0c;最近也刚好遇到相关问题&#xff0c;刚好稍微学习一下。 作者&#xff1a;高鹏&#xff08;八怪&#xff09;&#xff0c;《MySQ…

手把手将ReactJS项目部署到Ubuntu

我的新书《Android App开发入门与实战》已于2020年8月由人民邮电出版社出版&#xff0c;欢迎购买。点击进入详情 1.构建项目 npm run build 生成build目录&#xff1a; 2.上传项目 将build目录上传到Ubuntu。 可以使用Xftp工具。 3.启动项目 npm install -g serve serve -s …

原生JS做别踩白块游戏

思路 创建初始一个按钮并为他添加点击监听开始创建随机方块&#xff0c;并样式_box.offsetTop speed px结合setInterval使得方块不断下移创建和删除方块的原则&#xff1a;box.offsetTop>0&#xff08;可视区上部没有方块了&#xff09;时候需要创建一行方块&#xff0c;…

Apache DolphinScheduler 社区 2023 年度工作报告

随着 2023 年的日历逐渐翻至最后一页&#xff0c;我们欣喜地回顾 Apache DolphinScheduler 社区在这一年中所取得的成就和进步。这一年&#xff0c;我们不仅在社区规模和技术发展上取得了显著成就&#xff0c;还发布了大量的技术文章和博客&#xff0c;进一步丰富了我们的知识库…

【Java进阶篇】Java中Timer实现定时调度的原理(解析)

Java中Timer实现定时调度的原理 ✔️ 引言✔️JDK 中Timer类的定义✔️拓展知识仓✔️优缺点 ✔️ 引言 Java中的Timer类是用于计划执行一项任务一次或重复固定延迟执行的简单工具。它使用一个名为TaskQueue的内部类来存储要执行的任务&#xff0c;这些任务被封装为TimerTask对…

条款16:成对使用 new 和 delete 时要采用相同形式

下面程序的行为是未定义的。至少&#xff0c;stringArray指向的100个string对象中有99个不太可能被正确地析构。 被delete的指针指向单个对象还是一个对象数组&#xff1f;内存数组通常包括数组的大小&#xff0c;delete可以知道需要调用多少个析构函数。 使用delete时使用了方…