虽然我的工作中更多的是与数据库打交道,但是作为一个 Coder
,我觉得掌握前后端的 Web
技术来说是非常有必要的。
不仅可以帮助我们在工作中更好的理解其他岗位与你对接的人他的工作痛点,也能在公司需要人手的时候成为一个有力的应急帮手,比如之前公司的数据中台我就参与架构和部分开发任务,更重要的是我私下里可以运用一些快速框架来搭建一些有意思的网站,比如我的个人主页和个人博客都是我自学 java
和 js
所做出来的作品。
MVC
使用xml还是注解
@Component 组件没有明确规定其角色,作用在类级别上声明当前类为一个业务组件,被
Spring IOC 容器
维护
@Service 在业务逻辑层(Service)类级别进行声明
@Registory 在数据访问层(Dao)类级别进行声明
@Controller 在展现层(MVC)使用,标注当前类为一个控制器@Autowired 它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作,通过
@Autowired
的使用来消除set、get方法
@Inject 作用同上,是JSR-330 标准
@Resource 作用同上,是JSR-250 标准
以上三种注解在Set方法或属性上声明,一般情况下更习惯声明在属性上,代码简洁清晰@Configuration 将当前类声明为一个配置类,相当于一个xml配置文件
@ComponentScan 自动扫描包下标注有@Repository @Service @Controller
@Component 注解的类并有Spring IOC 容器
进行实例化和维护
@Bean 作用于方法上,声明当前方法的返回值是一个Bean对象
,相当于xml文件
中<bean></bean>
声明当前方法返回一个bean对象
@Value 获取properties文件
指定的key/value
作用是添加坐标相关配置,主要是各种依赖jar包
所谓元注解其实就是可以注解到别的注解上的注解,被注解的注解称之为组合注解,组合注解具备元注解的功能,主要的作用是消除重复注解
习惯大于配置目标
Spring Boot 的目标是快速运行,快速创建web应用,并独立机型部署(jar包方式,war包方式),相比于Spring框架是全新重写的框架
核心配置
主要是通过修改 /src/main/resources
目录下的 banner.txt
文件,如果没有则默认使用SpringBoot初始Banner
可以个性化制作Banner的网站制定相应的txt文件
默认是 application.properties
或者 application.yml
坐标依赖都配置在 pom.xml
中,如果添加了依赖以后标红可以使用 Maven -> Reload project
即可
@SpringBootConfiguration 本身是一个配置类,启动类启动的时候会加载
@EnableAutoConfiguration 组合了@AutoConfigurationPackage
&@Import(AutoConfigurationImportSelector.class)
@AutoConfigurationPackage 底层是一个@Import(AutoConfigurationPackage.Registrar.class),其会把启动类的包下组合都扫描到Spring容器中
@AutoConfigurationImportSelector 读取大量的自动配置类,完成自动配置,其读取的是classpath下的META-INF/spring.factories
下的配置文件
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
通过在 application.yml
中设置 spring.profiles.active=test/dev/prod
来动态切换不同环境,例如:
开发环境配置文件
application-dev.yml
server:
prot: 8098
测试环境配置文件
application-test.yml
server:
prot: 8097
生产环境配置文件
application-prod.yml
server:
prot: 8099
主配置文件
application.yml
spring:
profiles:
active: dev
SpringBoot默认使用 LogBack
日志系统,一般主流的日志都是用 log4j
日志系统
事务控制
全局异常
可以参考文章————Springboot系列-@ControllerAdvice使用 详细学习,这里后期会补上说明
此注解其实是一个增强的 Controller
,使用这个 Controller
,可实现三个方面的功能,因为这是SpringMVC提供的功能,所以可以在springboot中直接使用
package com.fx67ll.springboot.exceptions;
import com.fx67ll.springboot.po.vo.ResultInfo;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice
public class TestGlobalExceptionHandler {
@ExceptionHandler(value = Exception.class)
@ResponseBody
public ResultInfo exceptionHandler(Exception exception) {
ResultInfo resultInfo = new ResultInfo();
resultInfo.setCode(978);
resultInfo.setMsg("全局异常拦截,操作失败!");
// if (exception instanceof ParamsException) {
// ParamsException paramsException = (ParamsException) exception;
// resultInfo.setMsg(paramsException.getMsg());
// resultInfo.setCode(paramsException.getCode());
// }
return resultInfo;
}
}
数据校验
数据的校验是交互式网站一个不可或缺的功能,前端的 js校验
可以涵盖大部分的校验职责,如用户名唯一性,生日格式,邮箱格式校验等等常用的校验。
但是一般前端传来的数据是不可信的,前端校验过了,后端也应该重新校验,因为不排除用户绕过浏览器直接通过 Http工具
向后端请求的情况。
所以服务端的数据校验也是必要的,可以防止脏数据落到数据库中,如果数据库中出现一个非法的邮箱格式,也会让运维人员头疼不已。
@Null:被注释的元素必须为
null
@NotNull:被注释的元素不能为null
,可以为空字符串
@AssertTrue:被注释的元素必须为true
@AssertFalse:被注释的元素必须为false
@Min(value):被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value):被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value):被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value):被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max,min):被注释的元素的大小必须在指定的范围内
@Digits(integer,fraction):被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past:被注释的元素必须是一个过去的日期
@Future:被注释的元素必须是一个将来的日期
@Pattern(value):被注释的元素必须符合指定的正则表达式
@Email:被注释的元素必须是电子邮件地址
@Length:被注释的字符串的大小必须在指定的范围内
@Range:被注释的元素必须在合适的范围内
@URL:被注解的元素必须是一个URL
@NotEmpty:用在集合类上,不能为null
,并且长度必须大于0
@NotBlank:只能作用在String
上,不能为null
,而且调用trim()
后,长度必须大于0
静态资源
默认配置下,我们可以在 resources
资源目录下存放web应用静态资源文件
自定义静态资源路径,可以通过在 spring.resources.static-locations
后面追加一个配置 classpath:/你自定义的配置目录/
,例如:
application.yml
spring:
resources:
# 多个目录使用逗号隔开
static-loaction: classpath:/public/,classpath:/static/,classpath:/fx67ll/
打包和部署
热部署,就是在应用正在运行的时候升级软件,却不需要重新启动应用,主要应用在开发过程中
单元测试
<!--单元测试-->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-test</artifactid>
<scope>test</scope>
</dependency>
需要注意的是:
示例代码
package com.fx67ll.springboot.service;
import com.fx67ll.springboot.Starter;
import com.fx67ll.springboot.po.User;
import com.fx67ll.springboot.query.UserQuery;
import com.fx67ll.springboot.srevice.UserService;
import com.github.pagehelper.PageInfo;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
/**
* Service业务方法测试
*
* Junit中的RunWith注解 表示该类是单元测试的执行类
* SpringRunner 是 spring-test 提供的测试执行单元类(是Spring单元测试中SpringJUnit4ClassRunner的新名字)
* SpringBootTest注解 是执行测试程序的引导类
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Starter.class})
public class TestUserService {
// 日志的使用
private Logger logger = LoggerFactory.getLogger(TestUserService.class);
@Resource
private UserService userService;
@Before
public void before() {
logger.info("单元测试开始......");
}
@Test
public void testQueryUserById() {
logger.info("测试根据用户id查询......");
User user = userService.queryUserById(1);
logger.info("用户记录: {}", user.toString());
}
@Test
public void testSelectUserListByParams() {
logger.info("测试根据分页条件查询用户列表......");
UserQuery userQuery = new UserQuery();
PageInfo<user> pageInfo = userService.selectUserListByParams(userQuery);
logger.info(pageInfo.toString());
}
@After
public void after() {
logger.info("单元测试结束......");
}
}
</user>
MockMvc
是由 spring-test
包提供,实现了对 Http请求
的模拟,能够直接使用网络的形式,转换到 Controller
的调用,使得测试速度快、不依赖网络环境。
同时提供了一套验证的工具,结果的验证十分方便
提供一个唯一的 build方法
,用来构造 MockMvc
。
主要有两个实现: StandaloneMockMvcBuilder
和 DefaultMockMvcBuilder
,分别对应两种测试方式,
即独立安装和集成Web环境测试(并不会集成真正的 web环境
,而是通过相应的 Mock API
进行模拟测试,无须启动服务器)。
MockMvcBuilders提供了对应的创建方法 standaloneSetup
方法和 webAppContextSetup
方法,在使用时直接调用即可。
示例代码
PS:虽然提示测试通过,但是控制台一直没有打印出返回信息的记录,后期有空看看
package com.fx67ll.springboot.controller;
import com.fx67ll.springboot.Starter;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.mock.web.MockHttpServletResponse;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Starter.class})
@AutoConfigureMockMvc
public class TestUserController {
// 日志的使用
private Logger logger = LoggerFactory.getLogger(TestUserController.class);
@Autowired
private MockMvc mockMvc;
/**
* 模拟测试用户列表查询
* 其实就在模拟真实环境下前端对后端发起的请求
*/
@Test
public void apiTestSelectUserListByParams() throws Exception {
logger.info("开始模拟发送查询用户列表的请求......");
// 构建请求
MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.get("/user/list")
.contentType("text/html") // 设置请求头信息
.accept(MediaType.APPLICATION_JSON); // 设置请求Accept头信息
// 发送请求
ResultActions perform = mockMvc.perform(requestBuilder);
// 校验请求结果
perform.andExpect(MockMvcResultMatchers.status().isOk());
// 获取执行完成后返回的结果
MvcResult mvcResult = perform.andReturn();
// 得到执行后的响应
MockHttpServletResponse response = mvcResult.getResponse();
// 打印结果
logger.info(String.valueOf(response.getContentLength()));
logger.info("响应状态: ", response.getStatus());
logger.info("响应信息: ", response.getContentAsString());
logger.info("结束模拟发送查询用户列表的请求......");
}
@Test
public void apiTestQueryUserByUsername() throws Exception {
logger.info("开始模拟根据用户名查询用户记录的请求......");
// 构建请求并发送
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/user/name/admin"))
.andExpect(MockMvcResultMatchers.status().isOk()).andReturn();
// 打印结果
logger.info("响应状态: ", mvcResult.getResponse().getStatus());
logger.info("响应信息: ", mvcResult.getResponse().getContentAsString());
logger.info("结束模拟根据用户名查询用户记录的请求......");
}
}
Swagger2文档工具
在 pom.xml
中添加以下代码
<dependency>
<groupid>io.springfox</groupid>
<artifactid>springfox-swagger2</artifactid>
<version>2.9.2</version>
</dependency>
<dependency>
<groupid>io.springfox</groupid>
<artifactid>springfox-swagger-ui</artifactid>
<version>2.9.2</version>
</dependency>
主要是用在请求类上,用于说明该类的作用
示例
@Api(tags = "xx模块")
主要是用在请求的方法上,说明方法的作用
示例
@ApiOperation(value = "xx方法的作用", notes = "xx方法的备注说明")
主要是用在请求的方法上,说明方法的参数
详细参数说明
@ApiImplicitParams:用在请求的方法上,包含一组参数说明
@ApiImplicitParam:对单个参数的说明
name:参数名
value:参数的说明、描述
required:参数是否必须必填
paramType:参数放在哪个地方
· query --> 请求参数的获取:@RequestParam
· header --> 请求参数的获取:@RequestHeader
· path(用于restful接口)--> 请求参数的获取:@PathVariable
· body(请求体)--> @RequestBody User user
· form(普通表单提交)
dataType:参数类型,默认String,其它值dataType="Integer"
defaultValue:参数的默认值
单个参数示例
@ApiImplicitParam(name = "xxx", value = "xxx", required = true, paramType = "path", dataType = "String", defaultValue = "")
多个参数示例
@ApiImplicitParams({
@ApiImplicitParam(name = "xxxa", value = "xxxa", required = true, paramType = "body", dataType = "String", defaultValue = ""),
@ApiImplicitParam(name = "xxxb", value = "xxxb", required = true, paramType = "body", dataType = "String", defaultValue = ""),
})
主要是用在请求的方法上,说明错误响应的信息
详细参数说明
@ApiResponses:响应状态的说明。是个数组,可包含多个 @ApiResponse
@ApiResponse:每个参数的说明
code:数字,例如400
message:信息,例如"请求参数没填好"
response:抛出异常的类
多个参数示例,一般响应都是多个code,所以不写单个参数的示例了
@ApiResponses({
@ApiResponse(code = 200, message = "请求成功"),
@ApiResponse(code = 578, message = "请求参数错误"),
@ApiResponse(code = 404, message = "请求路径没有或页面跳转路径不对")
})
示例
@ApiModel(description = "用户实体类")
public class User {
@ApiModelProperty(value = "用户名", required = true, example = "0")
private Integer id;
@ApiModelProperty(value = "用户ID", required = true, example = "fx67ll")
private String userName;
@ApiModelProperty(value = "用户密码", required = true, example = "xxxxxxxx")
private String userPwd;
}
分布式缓存工具Ehcache
EhCache
是一个 纯Java
的进程内缓存框架,具有快速、精干等特点,是 Hibernate
中默认 CacheProvider
。
Ehcache
是一种广泛使用的开源 Java分布式缓存
,主要面向通用缓存, Java EE
和 轻量级容器
。
它具有内存和磁盘存储,缓存加载器,缓存扩展,缓存异常处理程序,一个 gzip
缓存 servlet
过滤器,支持 REST API
和 SOAP API
等特点。
SpringBoot缓存实现内部使用SpringCache实现缓存控制,这里集成Ehcache实际上是对SpringCache抽象的一种实现
可以参考文章————Spring Cache 简介 详细学习,这里后期会补上说明
开启缓存功能,一般放在启动类上
当我们需要缓存的地方越来越多,你可以使用 @CacheConfig(cacheNames = {"cacheName"})
注解在 Class
之上来统一指定 value
的值,
这时可省略 value
,如果你在你的方法依旧写上了 value
,那么依然以方法的 value
值为准
根据方法对其返回结果进行缓存,下次请求时,如果缓存存在,则直接读取缓存数据返回;如果缓存不存在,则执行方法,并把返回的结果存入缓存中,一般用在查询方法上
注意 value
后面要使用 ehcache.xml
文件中所列的 cache.name
单个参数示例代码
@Cacheable(value = "fx67llCache", key = "#xxx")
多个参数示例,采用拼接的方式
@Cacheable(value = "fx67llCache", key = "#xxx.xxx + '-' + #xxx.xxx + '-' + #xxx.xxx")
使用该注解标志的方法,每次都会执行,并将结果存入指定的缓存中。其他方法可以直接从响应的缓存中读取缓存数据,而不需要再去查询数据库,一般用在新增方法上
示例代码
@CachePut(value = "fx67llCache", key = "#xxx.xxx")
使用该注解标志的方法,会清空指定的缓存,一般用在更新或者删除方法上
示例代码
@CacheEvict(value = "fx67llCache", key = "#xxx")
该注解可以实现同一个方法上同时使用多种注解
定时调度工具Quartz
在日常项目运行中,我们总会有需求在某一时间段周期性的执行某个动作,比如每天在某个时间段导出报表,或者每隔多久统计一次现在在线的用户量等。
在SpringBoot中有Java自带的 java.util.Timer
类,也可以在启动类添加 @EnableScheduling
注解引入定时任务环境
springboot-quickstart springboot-mybatis springboot-mybatis-crud springboot-mybatis-crud-prod 快速入门 整合mybatis 整套crud操作 生产环境开发
我是 fx67ll.com,如果您发现本文有什么错误,欢迎在评论区讨论指正,感谢您的阅读!
如果您喜欢这篇文章,欢迎访问我的 本文github仓库地址,为我点一颗Star,Thanks~ 😃
转发请注明参考文章地址,非常感谢!!!
Original: https://www.cnblogs.com/fx67ll/p/springboot-quickstart.html
Author: fx67ll
Title: SpringBoot快速入门
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/599333/
转载文章受原作者版权保护。转载请注明原作者出处!