Spring Boot是一个框架,简化Spring应用的初始搭建以及开发过程
一、特点
简化Spring应用的初始搭建和开发过程。
提供特定的配置方式,减少样板化配置的需求。
内嵌容器,无需单独安装和配置外部容器。
为基于Spring的开发提供更快的入门体验,无需代码生成,也无需xml配置。
二、优点
使用 JavaConfig(@Configuration、@Bean等注解) 有助于避免使用 XML
--类型安全:使用JavaConfig时,你可以直接在你的配置类中引用其他bean或组件,这提供了类型安全的好处。与XML配置相比,你不需要担心字符串名称的拼写错误或类路径的错误。它提供了配置 Spring IoC 容器的纯 Java 方法。因此它有助于避免使用 XML 配置。
--易于重构:在JavaConfig中,你可以使用IDE的重构工具来重命名方法或类,而不需要手动搜索和替换XML文件中的字符串。可以按类型而不是按名称检索 bean,不需要任何强制转换或基于字符串的查找。
-可读性:对于熟悉Java的开发者来说,JavaConfig通常比XML更容易阅读和理解。
-减少错误:XML的某些特性(如条件语句、包含和替换等)可能会引入复杂性,并可能导致配置错误。JavaConfig提供了一种更直接的方式来定义和配置bean,减少了这些错误的可能性。
-强大的IDE支持:许多IDE(如IntelliJ IDEA和Eclipse)都提供了对Spring JavaConfig的强大支持,包括自动补全、导航和重构工具等。
-与Java代码集成:JavaConfig允许你在Java代码中直接定义和配置bean,这使得bean的定义和代码更紧密地集成在一起。你可以直接在配置类中引用其他Java类和方法,而不需要在XML文件中使用字符串引用。
-支持Java 8+的特性:JavaConfig支持Java 8及更高版本的语言特性,如Lambda表达式、方法引用和注解等。这使得你可以使用更现代、更简洁的语法来定义和配置bean。
避免大量的 Maven 导入和各种版本冲突。
--使用Spring Boot的父POM:
Spring Boot提供了一个父POM,它管理了大多数Spring Boot项目的常用依赖项的版本。通过在你的pom.xml文件中继承这个父POM,你可以自动获得这些依赖项的正确版本,而无需手动指定它们
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>你的Spring Boot版本</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
--使用Spring Boot的起步依赖(Starters):
Spring Boot的起步依赖是一组方便的依赖项描述符,你可以将它们包含在项目中,以获取一组相关的依赖项,而无需手动搜索和指定每个依赖项的版本。例如,如果你正在开发一个Web应用程序,你可以添加spring-boot-starter-web依赖项。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 其他依赖项 -->
</dependencies>
减少开发、快速开始开发
--没有单独的 Web 服务器需要。这意味着你不再需要启动 Tomcat,Glassfish 或其他任何东西。
--需要更少的配置 因为没有 web.xml 文件。只需添加用@ Configuration 注释的类,然后添加用@Bean 注释的方法,Spring 将自动加载对象并像以前一样对其进行管理。您甚至可以将@Autowired 添加到 bean 方法中,以使 Spring 自动装入需要的依赖关系中。
三、缺点
可能存在冲突:由于Spring Boot的自动配置特性,可能会出现配置冲突或不兼容的情况。在引入多个依赖启动器时,可能会出现版本冲突或依赖冲突的问题,需要开发人员进行手动调整和解决。
依赖管理较复杂:Spring Boot的自动依赖管理机制可能会导致项目依赖的版本冲突或不一致。在大型项目中,管理复杂的依赖关系可能会变得相当困难。需要开发人员进行仔细的依赖管理,以确保项目的稳定性和可维护性。
四、Spring Boot 中的监视器
监视器在Spring Boot中是一种特殊的应用程序或组件,用于实时跟踪和监视应用程序的各种指标。
它通过提供可视化的方式,帮助开发人员实时了解应用程序的运行状态和性能,从而及时发现和解决问题,提高应用程序的可靠性和稳定性。
组件
Spring Boot Actuator:作为Spring Boot框架中的一个重要组件,它提供了一组监视器功能,包括应用程序指标、健康检查、日志管理、端点监控和配置管理等。
Micrometer:与Spring Boot集成的度量库,用于收集应用程序的各种指标,并支持多种监控系统,如Prometheus、InfluxDB等。
核心功能
应用程序指标:实时跟踪应用程序的各种指标,例如响应时间、CPU使用率、内存使用情况等。
健康检查:检查应用程序的健康状况,包括是否正常运行、是否存在错误或异常情况等。
日志管理:记录应用程序的日志信息,包括错误日志、警告日志、调试日志等。
端点监控:通过HTTP请求访问特定的端点(如/actuator/health、/actuator/info、/actuator/metrics等),获取应用程序的相关信息,如运行状态、错误信息、性能指标、配置信息等。
集成与配置
监视器功能通常通过添加Spring Boot Actuator的依赖项到项目的构建配置文件中(如Maven的pom.xml)进行集成。
配置可以通过application.properties或application.yml文件进行,包括设置特定的端点是否启用、暴露哪些指标等
YAML
YAML 是一种人类可读的数据序列化语言。它通常用于配置文件。
与属性文件相比,如果我们想要在配置文件中添加复杂的属性,YAML 文件就更加结构化,而且更少混淆。可以看出 YAML 具有分层配置数据。
实现 Spring Boot 应用程序的安全性
为了实现 Spring Boot 的安全性,我们使用 spring-boot-starter-security 依赖项,并且必须添加安全配置。它只需要很少的代码。配置类将必须扩展 WebSecurityConfigurerAdapter 并覆盖其方法。
集成 Spring Boot 和 ActiveMQ
在 Spring Boot 应用中集成 ActiveMQ 的基本步骤
- 添加依赖
<dependencies>
<!-- Spring Boot Starter for ActiveMQ -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<!-- Spring Boot Starter for JMS
(Optional, if you need more JMS-specific features) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jms</artifactId>
</dependency>
<!-- If you need ActiveMQ's pool connection factory -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>YOUR_ACTIVEMQ_VERSION</version>
</dependency>
<!-- Other dependencies... -->
</dependencies>
- 配置 ActiveMQ
在 application.properties 或 application.yml 文件中配置 ActiveMQ 的连接信息。
对于 application.properties:
spring.activemq.broker-url=tcp://localhost:61616
spring.activemq.user=admin
spring.activemq.password=secret
# 如果你使用连接池
spring.activemq.pool.enabled=true
spring.activemq.pool.max-connections=5
对于 application.yml:
spring:
activemq:
broker-url: tcp://localhost:61616
user: admin
password: secret
pool:
enabled: true
max-connections: 5
- 创建消息发送者(Producer)
创建一个 Spring Bean 来发送消息到 ActiveMQ。
@Service
public class MessageSender {
@Autowired
private JmsTemplate jmsTemplate;
@Value("${activemq.queue}")
private String queueName;
public void sendMessage(String message) {
jmsTemplate.convertAndSend(queueName, message);
}
}
在 application.properties 或 application.yml 中定义队列名称:
activemq.queue=myQueue
- 创建消息接收者(Consumer)
使用 @JmsListener 注解来创建消息接收者。
@Component
public class MessageReceiver {
@JmsListener(destination = "${activemq.queue}")
public void receiveMessage(String message) {
System.out.println("Received message: " + message);
}
}
- 运行 Spring Boot 应用
现在可以运行 Spring Boot 应用,并使用 MessageSender 来发送消息,MessageReceiver 会接收并处理这些消息。 - (可选)配置消息转换器
默认情况下,JmsTemplate 使用 SimpleMessageConverter 来转换消息。如果需要自定义消息转换,可以创建一个自定义的 MessageConverter 并将其注入到 JmsTemplate 中。 - (可选)配置 ActiveMQ 连接工厂
如果需要更复杂的配置,例如设置连接超时、重试策略等,可以配置一个自定义的 ConnectionFactory 并将其注入到 JmsTemplate 或 JmsListenerContainerFactory 中。 - (可选)使用主题(Topics)而不是队列(Queues)
如果想要使用发布/订阅模型而不是点对点模型,可以将 JmsListener 的 destination 设置为一个主题,并使用 JmsTemplate 的 convertAndSend 方法发送消息到该主题。注意,在发布/订阅模型中,需要配置一个或多个订阅者来接收消息。
实现分页和排序
在 Spring Boot 中实现分页和排序通常涉及到与数据库交互,并且使用 Spring Data JPA 或 MyBatis 等持久层框架可以很容易地实现这些功能
- 添加依赖
首先,pom.xml(Maven)或 build.gradle(Gradle)中包含了 Spring Data JPA 的依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
- 创建实体和仓库
一个 User 实体和一个对应的 UserRepository
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Integer age;
// getters, setters, etc.
}
public interface UserRepository extends JpaRepository<User, Long> {
// 可以在这里定义自定义的查询方法
}
- 使用 Pageable 接口实现分页和排序
在 UserRepository 或服务层中,可以使用 Pageable 接口来实现分页和排序。Pageable 接口有一个实现类 PageRequest,可以用它来创建一个分页请求
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public Page<User> getUsers(int page, int size, String sortBy,
Sort.Direction direction) {
Sort sort = Sort.by(direction, sortBy);
Pageable pageable = PageRequest.of(page - 1, size, sort);
return userRepository.findAll(pageable);
}
}
page 是请求的页码(通常从 1 开始,但在编程中通常从 0 开始,所以我们需要 page - 1),size 是每页的大小,sortBy 是排序的字段名,direction 是排序的方向(Sort.Direction.ASC 或 Sort.Direction.DESC)
- 调用服务层方法并处理分页结果
在控制器中,可以调用服务层的方法来获取分页数据,并处理结果
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/paged")
public ResponseEntity<Page<User>> getPagedUsers(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
@RequestParam(defaultValue = "name") String sortBy,
@RequestParam(defaultValue = "ASC") Sort.Direction direction) {
Page<User> users = userService.getUsers(page, size, sortBy, direction);
return ResponseEntity.ok(users);
}
}
使用了 Spring MVC 的 @RequestParam 注解来从请求中获取分页和排序的参数
- 测试
现在可以启动 Spring Boot 应用并发送一个 GET 请求到 /users/paged 来测试分页和排序功能。
例如,要获取第一页(每页 10 条记录)并按名称升序排序的用户,可以发送一个 GET 请求到 /users/paged?page=1&size=10&sortBy=name&direction=ASC。
用 Spring Boot 实现 Swagger
--Swagger 是一套规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。
它允许开发人员为 RESTful Web 服务定义清晰的接口,然后 Swagger 工具可以根据这些接口生成相关的客户端和服务端代码、文档以及测试用例。
Swagger 规范包括 Swagger OpenAPI 规范(以前称为 Swagger 规范)和 Swagger UI。
--Swagger OpenAPI 规范(OpenAPI 3.0 或更高版本)是一种与语言无关的接口描述语言,用于描述 RESTful API。
它允许开发人员使用 YAML 或 JSON 格式定义 API 的结构,包括请求方法、请求和响应参数、安全性等。Swagger UI 是一个 HTML、JavaScript 和 CSS 集合,它可以从 OpenAPI 规范中动态生成一个可视化的 API 文档,并允许用户直接测试这些 API。
在 Spring Boot 项目中,实现 Swagger 步骤:
1.添加依赖:将 Swagger 相关的依赖(如 springfox-boot-starter)添加到项目的 pom.xml(Maven)或 build.gradle(Gradle)文件中。
2.配置 Swagger:创建一个配置类,使用 @Configuration 和 @EnableSwagger2(对于 Swagger 2.x)或 @EnableOpenApi(对于 OpenAPI 3.x 和更高版本)注解,配置 Swagger 的基本设置,如 API 的标题、描述、版本、联系信息等。
3.定义 API 文档:使用 Swagger 注解(如 @Api、@ApiOperation、@ApiParam 等)来定义 API 的文档信息,这些注解可以直接添加到控制器类和方法上。
4.启用 Swagger UI:配置 Swagger UI,使其能够加载和显示生成的 API 文档。
5.访问 Swagger UI:启动 Spring Boot 应用后,通过访问指定的 URL(如 /swagger-ui.html)来查看和使用 Swagger UI。
在 Spring Boot 项目中添加和配置 Swagger 2.x
// 添加依赖(Maven)
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version> <!-- 注意版本号,根据实际情况选择 -->
</dependency>
// 配置 Swagger
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build()
.apiInfo(metaData());
}
private ApiInfo metaData() {
return new ApiInfoBuilder()
.title("My API")
.description("API documentation for My App")
.version("1.0")
.license("Apache 2.0")
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
.build();
}
}
Spring Profiles
Spring Profiles是Spring框架中的一个功能,它允许开发者根据不同的环境(如开发环境、测试环境、生产环境等)来配置不同的Bean、属性和配置,从而实现在不同环境下应用程序的定制化配置
Spring Profiles 允许用户根据配置文件(dev,test,prod 等)来注册 bean
当应用程序在开发中运行时,只有某些 bean 可以加载,而在 PRODUCTION 中,某些其他 bean 可以加载。假设我们的要求是 Swagger 文档仅适用于 QA 环境,并且禁用所有其他文档。这可以使用配置文件来完成。Spring Boot 使得使用配置文件非常简单
- Profile定义
定义方式:可以通过在配置文件中使用@Profile注解或通过spring.profiles.active属性来定义不同的Profile。
示例:在配置类或Bean上使用@Profile注解来指定只在特定Profile下才生效。 - Profile激活
激活方式:通过spring.profiles.active属性来指定当前激活的Profile。可以通过命令行参数、环境变量、配置文件等方式来设置spring.profiles.active属性的值。
优先级:如果在多个地方设置了spring.profiles.active,优先级通常是从高到低的,如命令行参数 > 环境变量 > 配置文件。 - 条件化Bean注册
原理:Spring容器会根据当前激活的Profile来决定是否注册特定的Bean。
实现方式:可以使用@Profile注解或条件化的注解(如@ConditionalOnProperty、@ConditionalOnClass等)来实现条件化的Bean注册。 - 条件化配置
应用场景:Spring框架允许开发者在配置文件中根据Profile来定义不同的配置。
实现方式:可以使用application-{profile}.properties或application-{profile}.yml文件来定义特定Profile下的配置。 - 使用步骤
定义Profiles:在配置文件或Java类中使用@Profile注解来定义不同的Profiles。
配置环境:通过命令行参数、环境变量、配置文件等方式来设置spring.profiles.active属性,指定当前激活的Profile。
条件化注册Bean:在配置类或Bean上使用@Profile注解来指定只在特定Profile下才生效。
条件化配置:在配置文件中根据Profile来定义不同的配置。 - 示例
配置文件命名:创建不同的配置文件,且命名规则遵循application-${profile}.yml,例如application-dev.yml、application-test.yml、application-prod.yml。
激活方式:通过在application.yml中设置spring.profiles.active,或在执行有参启动时,在命令中指定--spring.profiles.active=test来激活特定的Profile。
Spring Batch
Spring Boot Batch 提供可重用的函数,这些函数在处理大量记录时非常重要,包括日志/跟踪,事务管理,作业处理统计信息,作业重新启动,跳过和资源管理。它还提供了更先进的技术服务和功能,通过优化和分区技术,可以实现极高批量和高性能批处理作业。简单以及复杂的大批量批处理作业可以高度可扩展的方式利用框架处理重要大量的信息。
FreeMarker
FreeMarker 是一个基于 Java 的模板引擎,最初专注于使用 MVC 软件架构进行动态网页生成。使用 Freemarker 的主要优点是表示层和业务层的完全分离。程序员可以处理应用程序代码,而设计人员可以处理 html 页面设计。最后使用 freemarker 可以将这些结合起来,给出最终的输出页面。
Spring Boot 异常处理
Spring 提供了一种使用 ControllerAdvice 处理异常的非常有用的方法。 我们通过实现一个ControlerAdvice 类,来处理控制器类抛出的所有异常。
- 使用@ControllerAdvice和@ExceptionHandler
这是Spring 3.2引入的一个功能,允许定义一个类来处理特定类型的异常。可以在该类上使用@ControllerAdvice注解,并在方法上使用@ExceptionHandler注解来指定要处理的异常类型
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public ApiErrorResponse handleException(Exception e) {
// 这里可以记录日志,或者返回自定义的错误信息
return new ApiErrorResponse("Error", e.getMessage());
}
// 可以为不同的异常类型定义不同的处理方法
@ExceptionHandler(value = CustomException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ApiErrorResponse handleCustomException(CustomException e) {
// 处理自定义异常
return new ApiErrorResponse("Custom Error", e.getMessage());
}
}
在上面的例子中,ApiErrorResponse是一个简单的类,用于封装错误信息。可以根据需要自定义这个类。
- 使用@ResponseStatus
如果自定义异常需要返回特定的HTTP状态码,可以在自定义异常类上使用@ResponseStatus注解。然后,可以像上面那样使用@ExceptionHandler来处理这个异常
@ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "Invalid data")
public class CustomException extends RuntimeException {
// ...
}
- 使用Spring Boot的ErrorController
Spring Boot提供了一个ErrorController接口,可以实现这个接口来定制全局的错误处理。但是,请注意,ErrorController主要用于处理在Spring MVC处理请求期间未捕获的异常。如果异常在@Controller或@RestController的方法中被捕获并处理,那么ErrorController将不会被调用。
@Controller
public class CustomErrorController implements ErrorController {
private static final String PATH = "/error";
@RequestMapping(value = PATH)
public ResponseEntity<Object> handleError(HttpServletRequest request) {
Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
if (status != null) {
int statusCode = Integer.valueOf(status.toString());
// 根据状态码返回不同的错误信息
if(statusCode == HttpStatus.BAD_REQUEST.value()) {
return new ResponseEntity<>("Bad Request", HttpStatus.BAD_REQUEST);
} else if(statusCode == HttpStatus.NOT_FOUND.value()) {
return new ResponseEntity<>("Not Found", HttpStatus.NOT_FOUND);
}
// ... 其他状态码的处理
return new ResponseEntity<>("Unknown Error", HttpStatus.INTERNAL_SERVER_ERROR);
}
return new ResponseEntity<>("Unknown Error", HttpStatus.INTERNAL_SERVER_ERROR);
}
@Override
public String getErrorPath() {
return PATH;
}
}
- 使用Spring Boot的ErrorAttributes
可以自定义ErrorAttributes来修改默认的错误信息。但是,请注意,这只会影响默认的/error端点的输出,不会改变通过@ExceptionHandler或@ResponseStatus返回的错误信息。 - 全局异常处理器
除了使用@ControllerAdvice,可以使用AOP(面向切面编程)来创建一个全局的异常处理器。但是,这种方法通常比使用@ControllerAdvice更复杂,因此不推荐在简单的场景中使用。
CSRF 攻击
CSRF 代表跨站请求伪造。这是一种攻击,迫使最终用户在当前通过身份验证的 Web 应用程序上执行不需要的操作。CSRF 攻击专门针对状态改变请求,而不是数据窃取,因为攻击者无法查看对伪造请求的响应。
WebSockets
WebSocket 是一种计算机通信协议,通过单个 TCP 连接提供全双工通信信道。
WebSocket 是双向的 -使用 WebSocket 客户端或服务器可以发起消息送。
WebSocket 是全双工的 -客户端和服务器通信是相互独立的。单个 TCP 连接 -初始连接使用 HTTP,然后将此连接升级到基于套接字的连接。然后这个单一连接用于所有未来的通信Light -与 http 相比,WebSocket 消息数据交换要轻得多
AOP
在软件开发过程中,跨越应用程序多个点的功能称为交叉问题。这些交叉问题与应用程序的主要业务逻辑不同。因此,将这些横切关注与业务逻辑分开是面向方面编程(AOP)的地方。
Apache Kafka
Apache Kafka 是一个分布式发布 - 订阅消息系统。它是一个可扩展的,容错的发布 - 订阅消息系统,它使我们能够构建分布式应用程序。这是一个 Apache 顶级项目。Kafka 适合离线和在线消息消费。
监视所有 Spring Boot 微服务
Spring Boot 提供监视器端点以监控各个微服务的度量。这些端点对于获取有关应用程序的信息(如它们是否已启动)以及它们的组件(如数据库等)是否正常运行很有帮助。但是,使用监视器的一个主要缺点或困难是,我们必须单独打开应用程序的知识点以了解其状态或健康状况。想象一下涉及 50 个应用程序的微服务,管理员将不得不击中所有 50 个应用程序的执行终端。
- 使用Spring Boot Actuator
--导入依赖:在Spring Boot微服务的pom.xml文件中,添加spring-boot-starter-actuator依赖。
--配置信息:在配置文件中(如application.yml或application.properties),配置Actuator的相关设置,以启用所需的端点。例如,通过配置management.endpoints.web.exposure.include属性为"*"来暴露所有端点。
--访问端点:启用Actuator后,可以访问如/actuator/health、/actuator/info、/actuator/metrics等端点来监视微服务的健康状况、信息和指标。 - 使用Spring Boot Admin
--Spring Boot Admin是一个开源的监控解决方案,它基于Spring Boot Actuator之上,为多个Spring Boot应用程序提供了可视化的监控界面。
--添加依赖:在每个微服务的pom.xml文件中,添加Spring Boot Admin客户端的依赖。
--配置Admin Server:设置一个Spring Boot Admin Server,它负责收集并展示所有注册微服务的监控信息。
--监控界面:通过Admin Server的Web界面,可以方便地查看所有微服务的运行状态、性能指标和健康状况。 - 自定义监控解决方案
--根据具体需求,可以开发自定义的监控解决方案。这可能涉及收集微服务的日志、指标、事件等数据,并通过API或消息队列将其发送到监控中心进行分析和展示。
--自定义监控解决方案可以提供更灵活、更贴合业务需求的监控功能,但也需要投入更多的开发和维护成本。 - 注意事项
--在启用任何监控功能时,都要注意保护敏感信息不被泄露。例如,不要在公共端点中暴露过多的系统信息或用户数据。
--监控工具的选择应根据实际需求和技术栈来决定。不同的监控工具有不同的优缺点和适用场景,需要仔细评估后做出选择。
--监控数据的收集和分析应该定期进行,以便及时发现并解决潜在问题。同时,也要确保监控系统的稳定性和可靠性,避免因为监控工具本身的问题而影响微服务的正常运行。