Spring与Spring Boot
从开发及架构上,Spring框架具有以下优点:
- Spring的依赖反转功能让我们可以开发出方便进行测试的代码。
- 提供了易用、灵活、强大的数据事务管理支持功能。
- Spring强大的开放基因,使得其可以和众多框架,如JAP/hibernate、JSF、Kafka、RabbitMQ、Thymeleaf等整合。
- 提供了标准化的Web应用开发支持Spring MVC。
Spring Boot框架所提供的自动配置机制可以完成这些配置,快速启动一个项目,并且在后续的开发上配置保持最简。
在使用上,Spring Boot通过提供一系列名称以spring-boot-starter开头的启动器帮助我们简化项目的依赖。
- spring-boot-starter-web:Web应用开发
- spring-boot-starter-logging:日志处理
- spring-boot-starter-jpa:数据存储管理
- spring-boot-starter-security:安全管理
- spring-boot-starter-actuator:应用监控
- spring-boot-starter-data-redis:Redis数据库集成
spring-boot-starter-amqp:消息中间件集成。
快速启动Spring Boot
2、编写应用引导类
@SpringBootApplication注解告诉Spring容器:使用该类作为所有Bean源,通过该起始点构建应用的上下文。
@SpringBootApplication注解继承自@EnableAutoConfiguration和@ComponentScan,通过该注解使得项目启动时Spring就会对该类所属目录下的所有子包进行扫描并根据SpringBoot的自动配置机制进行配置。
Application类的main()方法调用了SpringApplication.run(),该方法在项目启动时构建一个Spring容器,并返回一个ApplicationContext对象,也就是项目应用的上下文。
对于引导类来说其是整个应用启动的初始点,因为,如果在应用启动时需要进行某些初始化处理,那么最好都在该类中完成。
3、编写配置文件
Spring Boot配置文件支持properties和yml两种格式,默认文件名称都是application,存放在resources目录中。
4、运行项目
对后续将要编写的微服务来说,更多的时候是打包成一个部署单元。在打包时就会使用Maven脚本中配置的spring-boot-maven-plugin插件,然后通过mvn clean package命令将项目打包成一个Fat Jar,在生产环境下可以直接使用java -jar test.jar。
Fat jar是通过Mavne打包所生成的这种Jar不仅仅包含本项目中源码所编译生成的Java类文件,还会包含项目所依赖的第三方库及有关项目启动的相关信息。
spring-boot-starter-web默认依赖了spring-boot-starter-tomcat,通过该依赖,SpringBoot在启动应用时就会启动一个内嵌的Tomcat容器,并在该容器中运行项目。如果不想使用Tomcat作为启动容器,而是使用Jetty,那么可以在pom.xml文件中排除对Tomcat的依赖,并增加spring-boot-starter-jetty。使用SpringBoot构建实例项目
1、经典三层应用架构
架构分层采用最广泛三层架构开发客户端层UI层:主要用来与用户进行交互,显示数据并接受用户的输入。
- 应用层:关注业务规则的制定和业务流程的实现,负责与UI层进行交互及数据存储的处理。
- 业务逻辑层:定义业务实体(Domain),业务逻辑的具体实现(Service)。
- 接口层(API层):使用REST方式提供API接口,提供数据集业务处理(Controller)。
- 数据接口层(DAO):负责业务实体对象的数据处理(Repository)。
- 存储层:即持久层,主要用来保存我们的业务数据(Mysql、MongoDB、Redis或者文件存储系统)。
2、设计业务实体
清晰地识别出这些业务实体,以及它们之间如何交互及关联关系之后,才能进行下一步开发。
这些业务实体是开发系统的核心,一旦业务实体对象定义不合理,往往会造成业务逻辑实现的复杂度升高及系统灵活性降低,甚至可能需要重新设计开发。
3、实现数据管理
ORM(Object Relational Mapping)框架可以辅助将业务对象通过映射的方式存储到数据库中,而不需要使用最原始的SQL语句。
JPA(Java Persistence API)完成数据存储处理。通过JPA可以将业务与具体所要存储的数据库解耦,方便在多种数据库之间进行切换。
- @Entoty:指所注解的类会被认为是JPA的一个实体对象,JAP就会对该对象进行映射处理。
- @Id: 用来注解数据库主键,并且通过@GeneratedValue自动生成主键的方式,默认使用数据自增方式
- @OneToOne、@OneToMany、@ManyToOne、@ManyToMany:实体关联关系,用来处理业务实体之间一对一、一对多、多对一、多对多关系的声明。
- @Table :注解使用在业务实体类上,自定义实体类映射到数据库具体哪张表上。
- @Column :使用该注解自定义字段映射关系。
4、编写业务逻辑层
按照开发方式来说,设计和开发的顺序应该是:Entity->REST API->业务逻辑层->数据存储层,通过测试驱动的方式设计锁需要的功能。
DTO(Data Transfer Object):数据传输对象,用来处理跨进程或网络传输数据聚合容器。
5、编写RESTful API(Controller层)
Spring MVC针对Controller提供了两个注解@Controller和@RestController。
@RestController注解,在该类中所有使用了@RequestMapping的方法就会返回响应体(response body)。
@Controller注解,则会将HTML部分的代码也一起返回给调用者。
@RequestMapping注解,可以使用在方法或类上,如果是注解在类上,那么该类中所有注解的方法都会继承类中锁声明的属性。@GetMapping和@PostMapping,分别处理GET和POST请求。
6、数据库初始化
SpringBoot框架提供的Spring JDBC初始化DataSource特性,是在启动系统时检测classpath根目录下是否有schema.sql和data.sql脚本文件,如果这两个脚本文件都存在或其中一个,将会尝试加载并执行该脚本。如果脚本初始化产生异常,那么应用系统启动将会失败。
还可以在配置文件中通过设置spring.datasource.schema属性的值,定义数据库创建脚本的位置,通过spring.datasource.data属性设置数据初始化脚本的位置。如果将spring.datasource.initialize属性设置为false,则在启动时不将不执行数据库初始化处理。
Spring Boot特性
1、Spring Boot自动配置机制
Spring Boot自动配置机制从核心上可以总结两点:
通过@EnableAutoConfiguration为基于Spring的应用开启自动配置机制;
@EnableAutoConfiguration注解可以让Spring开启自动配置机制。开启后,Spring在系统启动时就会通过自动扫描项目class目录下所包含的依赖包,以及依赖的条件自动注册Bean,从而构建Spring的应用上下文。
在spring-boot-autoconfigure.jar中包含了一系列注解了@Configuration的自动配置类,这些类中还有@EnableConfigurationProperties注解,用来指定自动配置的一些条件。这些自动配置类则根据所扫描的依赖包,通过对所注解的@Condition条件来决定是否开启并注册到Spring的上下文中。通过一些列的@Conditional完成自动配置机制的实现。
@Condition可以根据一系列条件来决定是否启用某项配置,这些条件是:
- 在classpath下是否存在指定的类
- 在ApplicationContext中是否已存在指定类型的Bean
- 在指定目录下是否存在指定的文件
- 在配置文件中是否配置了指定的属性
- 指定的系统属性是否存在或不存在
- Spring Boot除了提供通用的@Condition注解外,还提供了一些开箱即用的条件注解
- @ConditionOnBean:在ApplicationContext中存在指定类型的Bean时启用
- @ConditionOnMissingBean:在ApplicationContext中不存在指定类型的Bean时启用
- @ConditionOnClass:在classpath下存在指定类时启用
- @ConditionOnMissingClass:在classpath下缺少指定类时启用。
- @ConditionOnProperties:当存在指定属性配置时启用。
- @ConditionOnResource:当存在指定资源时启用
- @ConditionOnWebApplication:当应用是一个Web应用时启用。
2、Spring Boot扩展属性配置
Spring Boot通过自动配置机制在系统启动时就自动创建了PropertyPlaceHolderConfigurer的Bean,并默认从class目录下的applicaiton.yml文件中加载作为系统的默认配置。
定义多个profile配置文件,application-{profile}.yml,可以从相应的配置文件中加载并覆盖默认的配置。
方便开发者将配置文件中所配置的数据直接注入到指定的对象中
- @Value:将配置参数的值直接注入到指定的Bean属性中。
- @ConfigurationProperties:通过指定的前缀,批量将配置的值注入一个Bean中。
- 属性配置校验注解,如@NutNull、@Email、@Min、@Max,可以辅助对参数配置进行有效性校验。
3、Spring Boot日志配置
默认情况下,Spring Boot依赖spring-boot-starter-logging,该依赖包为开发者的日志系统提供了一个抽象层接口,使开发者可以和多种日志系统直接进行集成,如SLF4J、Logback、Log4j2等。Spring Boot将默认集成Logback日志系统。
关于敏捷开发
当开发者使用敏捷开发时,重构就会成为日常开发过程中的常态。敏捷开发要求开发者每次的改进都不能太大,如果需要增加/改动的较大,那么这个时候或许就不能严格遵守敏捷开发的原则,需要在进行代码重构的同时添加一些必要的改进。
测试驱动开发(Test Driven Development,TDD)常用的一种开发驱动方式,指的是在编写业务逻辑之前先编写单元测试,首先会让测试失败,然后再通过实现具体的代码让测试通过。测试驱动开发可以很好地驱使开发者对业务需求的深层次思考,及早发现伪需求,从而保障系统功能的正确性。测试驱动开发的一个最大优势就是在保证不改变功能的情况下可以持续地对代码进行改进和重构,这样就可以让开发者既能够快速开发又能保证系统功能的稳定性。
Controller层的单元测试是非常重要的,一旦开发者为Controller编写了单元测试,也就为其所编写的业务功能增加了双保险,特使是进行微服务开发时,各微服务之间需要这些API才能够进行写作处理。当开发者更改了接口时,单元测试就会失败,这样就可以及早发现并进行更正。
关于RESTful API设计
1、以资源为中心进行URL设计
资源是RESTful API的核心,所有的操作都是针对某一特定资源进行的,所以简洁、清晰、结构化的URL设计是至关重要的。
2、正确使用HTTP方法及状态码
GET用来获取资源,POST用来创建资源(也可以用于更新资源),PUT用来更新资源,DELETE则是用来杀出资源,还有一个PATCH方法用来更新资源。
由于REST是基于HTTP协议的,因此对于用户请求的返回中应使用正确的状态码,以便客户端能够做出正确的处理。
- 2XX:请求正常处理并返回。
- 3XX:重定向,请求的资源位置发生变化。
- 4XX:客户端发送的请求有错误。
- 5XX:服务器端错误。
3、查询及分页处理原则
4、其他指导原则
- 使用JSON作为响应返回格式
- API域名
- API版本
- 错误处理