# SpringBootDemo
**Repository Path**: wangjxah/SpringBootDemo
## Basic Information
- **Project Name**: SpringBootDemo
- **Description**: SpringBoot框架学习
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 1
- **Created**: 2024-11-12
- **Last Updated**: 2024-11-12
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# SpringBootDemo
#### 项目介绍
SpringBoot框架学习
#### 项目框架
SpringBoot2.6.6
jdk1.8
#### 目录
- [项目搭建](#项目搭建)
- [pom.xml](#pom.xml)
- [返回json数据](#返回json数据)
- [整合FastJson](#整合FastJson)
- [热部署](#热部署)
- [捕获全局异常](#捕获全局异常)
- [整合JPA-Hibernate](#整合JPA Hibernate)
- [整合Jdbc Template](#整合Jdbc Template)
- [修改启动端口](#修改启动端口)
- [配置ContextPath](#配置ContextPath)
- [处理静态资源](#处理静态资源)
- [定时任务](#定时任务)
- [整合Druid监控配置](#整合Druid监控配置)
- [整合thymeleaf freemarker](#整合thymeleaf-freemarker)
- [自定义servlet](#自定义servlet)
- [自定义过滤器 (Filter)、监听器(Listener)](#自定义过滤器(Filter)、监听器(Listener))
- [拦截器](#拦截器)
- [CommandLineRunner](#CommandLineRunner(项目启动就去一些数据或做一些事情))
- [获取到系统环境变量和application配置文件中的变量](#获取到系统环境变量和application配置文件中的变量)
- [改变扫描包](#改变扫描包)
- [文件上传(多文件上传)](#文件上传(多文件上传))
- [引入xml配置文件](#引入xml配置文件)
- [整合redis](#整合Redis)
- [Spring Boot 的各种start](#SpringBoot的各种start)
- [整合Mybatis-Plus](#整合MyBatisPlus)
#### 项目搭建
使用IDE(idea),file→new project 选择 Spring Initializr 然后设置 groupId 和 artifactId(只能为小写字母),然后选择模板
然后选择项目保存路径即可
#### pom.xml
查看pom.xml会发现这么一段配置
org.springframework.boot
spring-boot-starter-parent
2.0.6.RELEASE
这段主要是提供依赖管理,引入之后在申明其它dependency的时候就不需要version了
若开发的为web工程pom.xml还需加入
org.springframework.boot
spring-boot-starter-web
spring官方解释说spring-boot-start-web包含了spring webmvc和tomcat等web开发的特性。
如果我们要直接Main启动spring,那么以下plugin必须要添加,否则是无法启动的。如果使用maven 的spring-boot:run的话是不需要此配置的
org.springframework.boot
spring-boot-maven-plugin
#### 项目启动
我们需要一个启动类,然后在启动类申明让spring boot自动给我们配置spring需要的配置,
比如:@SpringBootApplication,为了可以尽快让程序跑起来,我们简单写一个通过浏览器访问hello world字样的例子
(具体代码查看cn.ryh.helloword.SpringbootdemoApplication)类
然后运行该类的main方法即可启动程序,然后在浏览器中输入http://127.0.0.1:8080/。可以看到hell,word.
#### SpringBoot常用注解
1.注解列表
1.1:@Configuration
等同于spring的XML配置文件;使用Java代码可以检查类型安全.
1.2:@ComponentScan
组件扫描,可自动发现和装配一些Bean.让spring Boot扫描到Configuration类并把它加入到程序上下文。
1.3:@EnableAutoConfiguration
自动配置。SpringBoot自动配置(auto-configuration):尝试根据你添加的jar依赖自动配置你的Spring应用。
1.4:@Component
表示一个带注释的类是一个“组件”,成为Spring管理的Bean。当使用基于注解的配置和类路径扫描时,
这些类被视为自动检测的候选对象。同时@Component还是一个元注解。
可配合CommandLineRunner使用,在程序启动后执行一些基础任务。
1.5:@RestController
是@Controller和@ResponseBody的合集,表示这是个控制器bean,并且是将函数的返回值直
接填入HTTP响应体中,是REST风格的控制器(返回json格式)
1.6:@Resource
自动导入
1.7:@PathVariable
获取参数
1.8:@JsonBackReference
解决嵌套外链问题
1.9:@SpringBootApplication
包含了@ComponentScan、@Configuration和@EnableAutoConfiguration注解。
其中@ComponentScan让spring Boot扫描到Configuration类并把它加入到程序上下文。
[SpringBoot注解与详解](https://www.cnblogs.com/njqa/p/8177009.html)
[Spring注解与详解](https://www.cnblogs.com/alter888/p/9083963.html)
#### 返回json数据
其主要是在controller上加上@RestController注解,将@RestController注解换成@Controller并在方法加上@ResponseBody也行
其实Spring Boot也是引用了JSON解析包Jackson,那么自然我们就可以在Demo对象上使用Jackson提供的json属性的注解,对时间进行格式化,
对一些字段进行忽略等等。
#### 整合FastJson
在pom.xml中引入FastJson的jar包
com.alibaba
fastjson
1.2.47
配置FastJson
有俩配置方法:
1、实现WebMvcConfigurer接口,并重写configureMessageConverters方法
@Override
public void configureMessageConverters(List> converters) {
converters.removeIf(converter -> converter instanceof MappingJackson2HttpMessageConverter);
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
//处理中文乱码问题
List fastMediaTypes = new ArrayList<>();
fastMediaTypes.add(MediaType.valueOf(MediaType.APPLICATION_JSON_VALUE));
fastConverter.setSupportedMediaTypes(fastMediaTypes);
fastConverter.setFastJsonConfig(fastJsonConfig);
converters.add(fastConverter);
}
2、在启动类中,注入Bean : HttpMessageConverters
@Bean
public HttpMessageConverters fastJsonHttpMessageConverters() {
// 1、需要先定义一个 convert 转换消息的对象;
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
//2、添加fastJson 的配置信息,比如:是否要格式化返回的json数据;
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
//2-1 处理中文乱码问题
List fastMediaTypes = new ArrayList<>();
fastMediaTypes.add(MediaType.valueOf(MediaType.APPLICATION_JSON_VALUE));
fastConverter.setSupportedMediaTypes(fastMediaTypes);
//3、在convert中添加配置信息.
fastConverter.setFastJsonConfig(fastJsonConfig);
HttpMessageConverter> converter = fastConverter;
return new HttpMessageConverters(converter);
}
实体类中在某字段上使用@JSONField(serialize=false),然后查看是不是此字段就不返回了,如果是的话,那么恭喜你配置成功了
这里推荐使用第注入Bean的配置方式。
注:这也可以不写在App启动类中,防止所有配置都写这一个类中不好维护,我们也可新建一个类让实现WebMvcConfigurer 接口
然后重写其一下默认方法也能达到配置效果。例:fastjson/src/main/java/cn/ryh/fastjson/JsonConfigurer.java
(别忘在类名上加上@Configuration不然SpringBoot扫描不到该配置类)
#### 热部署
在pom.xml中加入
org.springframework.boot
spring-boot-devtools
true
org.springframework.boot
spring-boot-maven-plugin
true
每次修改后build一次即可
#### 捕获全局异常
在一个项目中的异常我们我们都会统一进行处理的,那么如何进行统一进行处理呢?
新建一个类GlobalDefaultExceptionHandler
在class注解上@ControllerAdvice
在方法上注解上@ExceptionHandler(value = Exception.class)具体代码(globalexception)
#### 整合JPA Hibernate
在application.yml配置文件中配置好数据库信息(具体查看application.yml文件中datasource部分),
并在pom.xml文件中引入相关驱动的jar包
org.springframework.boot
spring-boot-starter-data-jpa
然后在application.yml配置文件中配置JPA相关配置。
配置完后:在实体类上加上
@Entity //加入这个注解,该entity就会进行持久化了,
@Table(name = "user") //指定对应数据库的那张表
这俩个注解,并新建一个dao接口让其实现CrudRepository接口。具体代码(jpa)
在Spring Data的核心接口里面Repository是最基本的接口了, spring提供了很多实现了该接口的基本接口,
如:CrudRepository,PagingAndSortingRepository,SimpleJpaRepository,QueryDslJpaRepository等大量查询接口
更关于JPA的内容和操作请自行百度。
#### 整合Jdbc Template
在pom.xml加入jdbcTemplate的依赖
org.springframework.boot
spring-boot-starter-data-jdbc
在dao中注入JdbcTemplate,
@Resource
private JdbcTemplate jdbcTemplate;
(注:别忘记在dao类上加上@Repository注解,不然springBoot扫描不到该dao)
具体代码请查看:jdbctemplate
更多的Jdbc Template操作请查看
[Jdbc Template官方文档](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jdbc/core/JdbcTemplate.html)
#### 修改启动端口
在applicatoin.properties文件中加上
server.port = 端口号
#### 配置ContextPath
Spring boot默认是/ ,这样直接通过http://ip:port/就可以访问到index页面,如果要修改为http://ip:port/path/ 访问的话,
那么需要在application.yml文件中加入server.context-path = /你的path,比如:SpringBootDemo,
那么访问地址就是http://ip:port/SpringBootDemo 路径。
server.context-path=/SpringBootDemo
#### 处理静态资源
1.默认资源映射
启动应用的时候,可以在控制台中看到如下信息:
o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler
o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler
其中默认配置的 /** 映射到 /static (或/public、/resources、/META-INF/resources)
其中默认配置的 /webjars/** 映射到 classpath:/META-INF/resources/webjars/
优先级顺序为:META-INF/resources > resources > static > public (已进行测试)
通过访问:http://localhost:8888/1.png,会发现显示的是META-INF/resources下的图片,然后依次删除在访问。进行测试
可以在META-INF/resources > resources > static > public 这个几个目录下创建子目录,
让通过访问http://localhost:8888/子目录名/1.png 即可访问到。
2.自定义静态资源映射
2.1:代码配置
实现WebMvcConfigurer接口,并重写addResourceHandlers
/**
* 添加静态资源文件,外部可以直接访问地址
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//如下配置则能可以访问src/main/resources/mysource下面的文件
//该方式不会覆盖系统默认4种方式(同名定义除外),若将/mysource/** 改/** ,则会覆盖系统的配置
//可以多次使用 addResourceLocations 添加目录,优先级先添加的高于后添加的。
//例:registry.addResourceHandler("/**").addResourceLocations("classpath:/myres/").
// addResourceLocations("classpath:/static/");
//将静态资源路径设置到磁盘的目录
//可以直接使用addResourceLocations 指定磁盘绝对路径,同样可以配置多个位置,注意路径写法需要加上file:
// registry.addResourceHandler("/mysource/**").addResourceLocations("file:G:/mysource/");
registry.addResourceHandler("/mysource/**").addResourceLocations("classpath:/mysource/");
//如访问mysource文件夹下的1.jpg,则输入:localhost:8888/1.png
}
2.2:配置文件配置
在application.yml加入以下配置
# 默认值为 /**
spring.mvc.static-path-pattern =
# 默认值为 classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
spring.resources.static-locations = 这里设置要指向的路径,多个使用英文逗号隔开,
使用 spring.mvc.static-path-pattern 可以重新定义pattern,如修改为 /mysource/** ,
则访问static等目录下的1.png文件应该为localhost:8888/mysource/1.png,修改之前为 localhost:8888/1.png
使用 spring.resources.static-locations 可以重新定义 pattern 所指向的路径,支持 classpath: 和 file
而且这里的配置是覆盖默认配置,所以需要将默认的也加上,否则默认的将不被当做静态资源路径
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,\
classpath:/static/,classpath:/public/,classpath:/mysource/,file:G:/mysource/}
classpath指的是系统环境变量,file:指定的一个具体的硬盘路径
总结:代码配置和配置文件配置可以一起使用
#### 定时任务
通过@EnableScheduling注解开启对计划任务的支持
通过@Scheduled声明该方法是计划任务
使用cron属性可按照指定时间执行,cron是UNIX和类UNIX(Linux)系统下的定时任务
@Scheduled(cron = "0/5 * * * * ?") // 每5秒执行一次
使用fixedRate属性每隔固定时间(毫秒)执行
@Scheduled(fixedRate = 5000)
具体代码请看:cn.ryh.scheduled.SchedulingConfig 类
#### 整合Druid监控配置
Spring Boot默认的数据源是:org.apache.tomcat.jdbc.pool.DataSource
1、在pom.xml中加入druid依赖包
com.alibaba
druid-spring-boot-starter
1.2.8
配置application.yml加入数据库源类型等参数
具体配置请看application.yml中的Druid
启动项目后访问 http://127.0.0.1:8888/SpringBootDemo/druid3/index.html 即可查看数据源及SQL统计等
2、编写druid servlet和filter提供监控页面访问
具体代码请查看:cn.ryh.druid.servlet.DruidStatViewServlet 和 cn.ryh.druid.filter.DruidStatFilter
这里还需要在app启动类上添加@ServletComponentScan 注解
上配置的监控方式是使用了原生的servlet,filter方式,然后通过@ServletComponentScan进行启动扫描包的方式进行处理的,
可以发现我们的servlet,filter根本没有任何的编码。
启动项目后访问 http://127.0.0.1:8888/druid/index.html 即可查看数据源及SQL统计等
3、使用无需添加@ServletComponentScan 注解方式进行配置
1、使用代码注册Servlet
具体代码查看:cn.ryh.druid.config.DruidConfiguration
然后启动项目后访问 http://127.0.0.1:8888/druid2/index.html 即可查看数据源及SQL统计等。
第3种和第1种纯配置的方案,同时存在时第1中方案不会生效。第2种和其他俩种方案都兼容,推荐使用第三种方式
#### 整合thymeleaf freemarker
1、整合thymeleaf
Spring Boot默认就是使用thymeleaf模板引擎的,所有只需在pom.xml中引入thymeleaf依赖即可
org.springframework.boot
spring-boot-starter-thymeleaf
Thymeleaf缓存在开发过程中,肯定是不行的,那么就要在开发的时候把缓存关闭,只需要在application.yml加入
spring.thymeleaf.cache=false
配置即可
编写模板文件src/main/resouces/templates/helloTmtl.html
编写controller cn.ryh.thymeleaf.ThyMeleafController.java
然后访问:http://localhost:8888/thyMeleafController/helloTmtl
2、整合freemarker
在pom.xml加入freemarker的依赖
org.springframework.boot
spring-boot-starter-freemarker
然后在application.yml配置文件中加入FREEMARKER配置(具体配置查看application.yml文件)
编写模板文件:src/main/resouces/templates/helloFmtl.html
编写controller: cn.ryh.freemarker.FreeMarkerController.java
然后访问:http://localhost:8888/freeMarkerController/helloFmtl
#### 自定义servlet、过滤器(Filter)、监听器(Listener)
1、代码注册
代码注册通过ServletRegistrationBean、 FilterRegistrationBean 和 ServletListenerRegistrationBean 获得控制。
编写servlet:cn.ryh.servlet.CodeServlet
在app启动类中注册servlet
/**
* 注册Servlet.不需要添加注解:@ServletComponentScan
* @return
*/
@Bean
public ServletRegistrationBean MyServlet1(){
return new ServletRegistrationBean(new CodeServlet(),"/codeServlet/*");
}
访问:http://localhost:8888/codeServlet
2、注解方式注册
在 SpringBootApplication 上使用@ServletComponentScan注解后,Servlet、Filter、Listener
可以直接通过 @WebServlet、@WebFilter、@WebListener 注解自动注册,无需其他代码。
编写servlet:cn.ryh.servlet.AnnotationServlet
在app启动类上添加@ServletComponentScan 注解
访问:http://localhost:8888/annotationServlet
3、通过实现ServletContextInitializer接口,重写其onStartup()方法
重写其onStartup:cn.ryh.App.onStartup
写servlet:cn.ryh.servlet.InterfaceServlet
访问:http://localhost:8888/interfaceServlet
过滤器(Filter)和监听器(Listener)的注册方法和 Servlet 一样
过滤器编写:查看cn.ryh.filter
过滤器代码注册:查看cn.ryh.App.codeFilter方法
过滤器接口注册:查看cn.ryh.App.onStartup方法
过滤器注解注册:在 SpringBootApplication 上使用@ServletComponentScan注解,
查看:cn.ryh.filter.AnnotationFilter
监听器编写:查看cn.ryh.listener
监听器代码注册:查看cn.ryh.App.codeServletContextListener 和cn.ryh.App.codeSessionListener 方法
监听器接口注册:查看cn.ryh.App.onStartup方法
监听器注解注册:在 SpringBootApplication 上使用@ServletComponentScan注解,
查看:cn.ryh.listener.AnnotationServletContextListener和cn.ryh.listener.AnnotationSessionListener
然后在写一个controller测试SessionListener:cn.ryh.listener.controller.SessionController
然后项目启动的过程中我们会看到输出
InterfaceServletContextListener 初始化
CodeServletContextListener 初始化
AnnotationServletContextListener 初始化
AnnotationFilter过滤器初始化
InterfaceFilter过滤器初始化
CodeFilter过滤器初始化
服务启动后,访问http://localhost:8888/sessionController/sessionListener 会看到输出:
CodeFilter过滤器执行过滤操作
AnnotationFilter过滤器执行过滤操作
InterfaceFilter过滤器执行过滤操作
InterfaceSessionListener 初始化
CodeSessionListener 初始化
AnnotationSessionListener 初始化
AnnotationSessionListener 销毁
CodeSessionListener 销毁
InterfaceSessionListener 销毁
#### 拦截器
Web开发中,我们除了使用 Filter 来过滤请web求外,还可以使用Spring提供的HandlerInterceptor(拦截器)。
HandlerInterceptor 的功能跟过滤器类似,但是提供更精细的的控制能力:在request被响应之前、request被响应之后、
视图渲染之前以及request全部结束之后。我们不能通过拦截器修改request内容,
但是可以通过抛出异常(或者返回false)来暂停request的执行。
配置拦截器也很简单,Spring 为什么提供了基础类WebMvcConfigurerAdapter,只需要重写 addInterceptors 方法添加注册拦截器
实现自定义拦截器只需要3步:
1、创建我们自己的拦截器类并实现 HandlerInterceptor 接口,并重写preHandle、postHandle和afterCompletion 方法
2、创建一个Java类继承WebMvcConfigurerAdapter,并重写 addInterceptors 方法。
3、实例化我们自定义的拦截器,然后将对像手动添加到拦截器链中(在addInterceptors方法中添加)。
具体代码请看:cn.ryh.interceptor
然后启动项目,访问http://localhost:8888/jdbcTemplateController/getUser 在控制台会看到输出:
>>>MyInterceptorOne>>>>>>>在请求处理之前进行调用(Controller方法调用之前)
>>>MyInterceptorTwo>>>>>>>在请求处理之前进行调用(Controller方法调用之前)
>>>MyInterceptorTwo>>>>>>>请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
>>>MyInterceptorOne>>>>>>>请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
>>>MyInterceptorTwo>>>>>>>在整个请求结束之后被调用,也就是在DispatcherServlet
渲染了对应的视图之后执行(主要是用于进行资源清理工作)
>>>MyInterceptorOne>>>>>>>在整个请求结束之后被调用,也就是在DispatcherServlet
渲染了对应的视图之后执行(主要是用于进行资源清理工作)
拦截器正常情况执行顺序
preHandle按拦截器定义顺序调用
postHandle按拦截器定义逆序调用
afterCompletion按拦截器定义逆序调用
postHandle在拦截器链内所有拦截器返成功调用
afterCompletion只有preHandle返回true才调用
例:
假设有5个拦截器编号分别为12345,若一切正常则方法的执行顺序是12345的preHandle,54321的postHandle,54321的afterCompletion。
若编号3的拦截器的preHandle方法返回false或者抛出了异常,接下来会执行的是21的afterCompletion方法。
而45的preHandle方法不会执行,因为postHandle在拦截器链内所有拦截器返成功调用,所以一个postHandle也不会被调用。
因为afterCompletion只有preHandle返回true才调用,所以21的afterCompletion方法会被执行
所以我们在写一个拦截器的时候要谨慎的处理preHandle中的异常,因为这里一旦有异常抛出就不会再受到这个拦截器的控制。
12345的preHandle的方法执行过之后,若某个拦截器的postHandle方法出现了异常,假设是4的postHandle出现异常,
那么321的postHandle方法都不会被执行,因为只要12345的preHandle方法执行完,当前拦截器的拦截器就会记录成编号5的拦截器,
而afterCompletion总是从当前的拦截器逆向的向前执行,所以接下来会执行54321的afterCompletion方法。
在preHandle()中,也可以直接处理响应,然后返回false表示无需调用Controller方法继续处理了,
通常在认证或者安全检查失败时直接返回错误响应。在postHandle()中,因为捕获了Controller方法返回的ModelAndView,
所以可以继续往ModelAndView里添加一些通用数据,很多页面需要的全局数据如Copyright信息等都可以放到这里,
无需在每个Controller方法中重复添加。
#### CommandLineRunner(项目启动就去一些数据或做一些事情)
只需新建一个类实现CommandLineRunner 接口,实现其run方法
在类上加上@@Component 和 @Order(value = 1) 注解
@Component 注解可配合CommandLineRunner使用,在程序启动后执行一些基础任务。
@Order 注解 设置执行优先级是按value值从小到大顺序
#### 获取到系统环境变量和application配置文件中的变量
在pom.xml中引入
org.springframework.boot
spring-boot-configuration-processor
true
1、读取核心配置文件,指在resources根目录下的application.yml或application.yml
1.1:使用@Value("${键名}")
@Value("${service.name}")
private String name;
1.2:使用Environment,env.getProperty("键名")
@Resource
private Environment env;
String name = env.getProperty("service.name");
1.3:使用@ConfigurationProperties(prefix = "spring.datasource")
使用@ConfigurationProperties注解要保证属性名和配置文件下的名字一致才可完成注入
具体代码查看:cn.ryh.environment.controller.ReadApplicationConfig 和 cn.ryh.environment.entity.ApplicationConfig
2、读取自定义配置文件
也可以使用@Value("${键名}")注解和@ConfigurationProperties(prefix = "配置前缀")注解
但是需要加上@PropertySource(value = "classpath:自定义配置文件路径")注解一起使用才行。不然其还是去读核心配置文件了。
@PropertySource 默认只能读取.properties文件,所以需要自己实现一个能够解析yml文件类,并指定解析工厂为我们自定义的解析类
factory = YmlPropertySourceFactory.class
具体代码请看:cn.ryh.environment.controller.ReadMyConfigController 和 cn.ryh.environment.entity.MyConfig
#### 改变扫描包
Spring Boot默认会扫描启动类同包以及子包下的注解
那么如何进行改变这种扫描包的方式呢,原理很简单就是:在App启动类上,使用@ComponentScan注解进行指定要扫描的包以及要扫描的类
@ComponentScan(basePackages={"包路径","包路径2"})
可以使用:@ComponentScan(basePackageClasses={"类路径","类路径2"},basePackages={"包路径","包路径2"})
若使用@ComponentScan(basePackages={"包路径","包路径2"})指定扫描包路径,那么App启动类同包以及子包下都不会被扫描了,
这是我们也需要将App启动类的包路径也加入进去即可。
具体代码请看:cn.ryh.App 和 cn.test
#### 文件上传(多文件上传)
编写前台页面:templates/updateLoad.html 和 templates/multiFileUpload.html
编写Controller:cn.ryh.fileupload.FileUploadController
在app启动类加上
/**
* 设置文件大小限制
* @return
*/
@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
// 设置文件大小限制 ,超了,页面会抛出异常信息,这时候就需要进行异常信息的处理了;
factory.setMaxFileSize(DataSize.ofMegabytes(1024));
// 设置总上传数据总大小
factory.setMaxRequestSize(DataSize.ofMegabytes(2048));
//设置存储文件的目录位置 new File("").getCanonicalPath()项目根路径
try {
factory.setLocation(new File("").getCanonicalPath()+"\\");
} catch (IOException e) {
e.printStackTrace();
}
return factory.createMultipartConfig();
}
可在这不设置统一存储文件位置,但需要在
multipartFile.transferTo(new File(newName));时加存储文件位置,为每个文件设置存储位置
multipartFile.transferTo(new File(new File("").getCanonicalPath()+"\\"+newName));
#### 引入xml配置文件
新建俩个类文件,testImportXmlOne、testImportXmlTwo.
一个放在SpringBoot可以扫描到的位置一个放在扫描不到的位置(SpringBoot默认会扫描启动类同包以及子包下的注解)
可以扫描到的位置:cn.ryh.importxml.testImportXmlOne
无法扫描到的位置:cn.test.importxml.testImportXmlTwo
编写玩后直接启动可以在控制台看到以下输出:
testImportXmlOne
因为testImportXmlTwo的位置 SpringBoot扫描不到所以 testImportXmlTwo 未能打印。
现在新建一个xml配置文件,注入testImportXmlTwo 路径:application-bean.xml
在新建一个xmlConfigClass配置类,该类要确保能被SpringBoot扫描到.
其路径:cn.ryh.importxml.xmlConfigClass
然后启动项目可以在控制台看到以下输出:
testImportXmlOne
testImportXmlTwo
查看cn.ryh.importxml.xmlConfigClass,可以看到就只有俩个注解
@Configuration
@ImportResource(locations = "classpath:application-bean.xml")
@Configuration 注解表示该类为SpringBoot的配置类
@ImportResource 注解加载XML配置文件
我其实也可以不创建xmlConfigClass类,直接在App启动类上加上@ImportResource注解效果也是一样的,
但如果所有配置读写在App启动类中这样就会不好维护,所有建议新建一个类然后使用@Configuration注解 表明该类为SpringBoot的配置类
如果只是要SpringBoot注入一些其默认扫描,扫描不到的类,可以修改SpringBoot扫描包,修改方式见上文[改变扫描包]
#### 整合Redis
在pom.xml文件中引入依赖
org.springframework.boot
spring-boot-starter-redis
org.apache.commons
commons-pool2
2.11.1
org.springframework `_****_`
spring-context-support
编写RedisCacheConfig配置类:cn.ryh.redis.singleredis.RedisCacheConfig.redisTemplate
编写RedisService让我们能更好操作redisTemplate:cn.ryh.redis.singleredis.RedisUtil
测试:看 cn.ryh.helloword.SpringbootdemoApplicationTests 和 cn.ryh.redis.singleredis.controller.SingleRedisController
将redis作为缓存
先编写使用jpa读数据库操作。
cn.ryh.redis.singleredis.controller.RedisUserController
cn.ryh.redis.singleredis.dao.RedisUserDao
cn.ryh.redis.singleredis.service
在cn.ryh.redis.singleredis.RedisCacheConfig类上加上@EnableCaching注解,
并让其实现CachingConfigurerSupport接口,并重写keyGenerator方法。
并编写缓存管理器
cn.ryh.redis.singleredis.RedisCacheConfig.cacheManager
在RedisUserService 添加俩个缓存方法redisCacheFindById 和 redisCacheDelById
并在cn.ryh.redis.singleredis.service.impl.RedisUserServiceImpl实现该俩方法,并在方法上加上@Cacheable(value="")注解和
@CacheEvict(value="")注解
编写测试类:cn.ryh.redis.singleredis.controller.RedisUserController
启动项目,访问http://localhost:8888/SpringBootDemo/redisUserController/redisCacheFindById
在控制台看到输出:
RedisUserServiceImpl.redisCacheFindById.从数据库中读取.
Hibernate: select user0_.id as id1_0_0_, user0_.........
loaded=id:27username:景甜birthday:2017-03-29sex:1address:金刚骷髅岛
cached=id:27username:景甜birthday:2017-03-29sex:1address:金刚骷髅岛
RedisUserServiceImpl.redisCacheFindById.从数据库中读取.
Hibernate: select user0_.id as id1_0_0_, user0_..........
loaded2=id:1username:测试birthday:nullsex:nulladdress:null
很明显 loaded和cached之间没有打印从数据库中读取,说明我们的缓存设置成功了。
这里设置缓存时有几个坑,
1、要缓存的对象需要实现Serializable接口 序列化 并设置private static final long serialVersionUID = 1L;
2、读和存都要序列化且一致,不然会报类型转化异常
redis集群
配置见:cn/ryh/redis/clusterredis/RedisClusterConfig.java
这里仅仅是连接redis集群,若要将其设置为缓存,可以参考单机版的redis缓存配置。
spring-boot-starter-data-redis 2.1.0版本是使用Lettuce连接池。若要使用jredis连接池可以将spring-boot-starter-data-redis
版本降低,或者另外引入
#### SpringBoot的各种start
1、spring-boot-starter
Spring Boot核心starter,包含自动配置、日志、yal配置文件支持
2、spring-boot-starter-actuator
准生产特性、用于监控和管理应用
3、spring-boot-starter-remote-shell
提供基于ssh协议的监控和管理
4、spring-boot-starter-amqp
使用spring-rabbitlai zhichi AMQP
5、spring-boot-starter-aop
使用spring-aop和AspectJ支持面向切面编程
6、spring-boot-starter-batch
对Spring Batch的支持
7、spring-boot-starter-cache
对Spring Cache的抽象支持
8、spring-boot-starter-cloud-connectors
对云平台(Cloud Foundry、Heroku)提供的服务提供简化的连接方式
9、spring-boot-starter-data-elasticsearch
通过spring-data-elasticsearch对Elasticsearch支持
10、spring-boot-starter-data-gemfire
通过spring-data-gemfire对分布式存储GemFire的支持
11、spring-boot-starter-data-jpa
对JPA的支持,包含spring-data-jpa、spring-orm和hibernate
12、spring-boot-starter-mongodb
通过spring-data-mongodb,对mongodb的支持
13、spring-boot-starter-rest
通过spring-data-rest-webmvc将Spring Data repository暴露为REST形式服务
14、spring-boot-starter-solr
通过spring-data-solr对Apache Solr数据检索的支持
15、spring-boot-starter-freemarker
对Freemarker模板引擎的支持
16、spring-boot-starter-groovy-templates
通过spring-hateoas对基于HATEOAS的REST形式网络服务支持
17、spring-boot-starter-hornetq
通过HornetQ对JMS的支持
18、spring-boot-starter-integration
对系统集成框架spring-integration支持
19、spring-boot-starter-jdbc
对JDBC数据库的支持
20、spring-boot-starter-jersey
对Jersery REST形式网络服务支持
21、spring-boot-starter-jta-atomikos
通过Atomikos对分布式事务的支持
22、spring-boot-starter-mail
对javax.mail的支持
23、spring-boot-starter-mobile
对spring-mobile的支持
24、spring-boot-starter-mustache
对Mustache模板引擎的支持
25、spring-boot-starter-redis
对Redis的支持,包含spring-redis
26、spring-boot-starter-security
对spring-security的支持
27、spring-boot-starter-social-facebook
对Facebook支持
28、spring-boot-starter-social-linkedin
对linkedin支持
29、spring-boot-starter-social-twitter
对Twitter支持
30、spring-boot-starter-test
对常用测试框架JUnit、Hamcrest和Mockito的支持,包含spring-test模块
31、spring-boot-starter-thymeleaf
对Thymeleaf模板引擎的支持,包含于Spring整合的配置
32、spring-boot-starter-velocity
对Velocity模板引擎的支持
33、spring-boot-starter-web
对Web项目开发支持,包含Tomcat和Spring MVC
34、spring-boot-starter-Tomcat
Spring Boot默认Servlet容器
35、spring-boot-starter-Jetty
使用Jetty作为Servlet容器
36、spring-boot-starter-undertow
使用Undertow作为Servlet容器
37、spring-boot-starter-logging
Spring Boot默认日志框架logback
38、spring-boot-starter-log4j
支持使用Log4J日志框架
39、spring-boot-starter-websocket
对websocket的支持
40、spring-boot-starter-ws
对Spring Web Service支持
#### 整合MyBatisPlus
1、基础配置
在pom.xml中添加
com.baomidou
mybatis-plus-boot-starter
3.5.1
在主启动类上加上@MapperScan注解
//配置mapper文件扫描,这样就省的每个mapper类上去些@mapper注解
@MapperScan(basePackages = {"cn.ryh.**.mapper"})
新建对应的实体类并使用@TableName("user")注解,来标识实体类对应数据库中的那张表
新建mapper并继承com.baomidou.mybatisplus.core.mapper.BaseMapper泛型填入对应的实体,就实现了对应实体表CRUD 功能
注意:mapper一定得建在@MapperScan注解能扫描得到的地方,或者在mapper接口上增加@mapper注解
测试见cn.ryh.mybatisplus.mapper.UserMapperTests类。
2、配置日志
在application.yml配置文件中增加
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
3、条件构造器
具体参考 https://baomidou.com/pages/10c804/#abstractwrapper
4、主键策略
当未设置id,其会自动帮我们填写。默认为雪花算法+UUID(不含中划线)
若是需要使用数据库主键的自动递增,则需要在实体类中加上@TableId(type = IdType.AUTO)注解
(前提是数据库主键设置了自动递增)
注解详细说明见: https://baomidou.com/pages/223848/
若是数据库的自增和雪花算法+UUID不能满足我们的需求时,例如使用Oracle的Sequnce作为主键自增
这时需在实体类上加上@KeySequence(value = "SEQ_ORACLE_STRING_KEY", clazz = String.class)注解,
且@TableId(type = IdType.INPUT) 的type必须使用 INPUT
并加入
@Bean
public IKeyGenerator keyGenerator() {
return new OracleKeyGenerator();
}
配置。如果内置支持不满足你的需求,可实现 IKeyGenerator 接口来进行扩展.
测试见cn.ryh.mybatisplus.mapper.UserMapperTests.testInsert。
5、逻辑删除
在表和实体中增加 deleted 字段,并在 deleted 字段上增加 @TableLogic 注解,
在yml配置文件中加入
mybatis-plus:
global-config:
db-config:
logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
6、自动填充
在实体类中将需要自动填充的字段加上@TableField(value = "create_time",fill = FieldFill.INSERT)注解
并配置填充处理器,如下:
@Bean
public MetaObjectHandler myMetaObjectHandler(){
return new MetaObjectHandler() {
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill ....");
// 起始版本 3.3.3(推荐)
// 设置需要填充的字段,以及填充的值
this.strictInsertFill(metaObject, "createTime", LocalDateTime::now, LocalDateTime.class);
this.strictInsertFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class);
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill ....");
// 起始版本 3.3.3(推荐)
// 设置需要填充的字段,以及填充的值
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class);
}
};
}
然后进行添加,或者修改查看对应的sql可以看到其为我们自动填值了
7、分页查询
Page page = new Page<>(1, 3);
Page selectPage = userMapper.selectPage(page, null);
List userList = selectPage.getRecords();
userList.forEach(System.out::println);
/**
* 配置插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 添加 分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
代码见: cn.ryh.mybatisplus.mapper.UserMapperTests.testPaginationInnerInterceptor
8、乐观锁
在表和实体中增加version字段,并在version字段上增加@version 注解,然后再配置乐观锁拦截器
/**
* 配置插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 添加 乐观锁
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
// 添加 分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
代码见 cn.ryh.mybatisplus.mapper.UserMapperTests.testOptimisticLocker
9、性能分析插件
pom.xml中加入
p6spy
p6spy
3.9.1
增加spy.properties 配置文件。
修改对应的 driver-class-name 和url。
注意若和druid一起使用的话 spring.datasource.druid.filters 不能配置 wall
10、代码自动生成插件
1、mybatisX插件
2、代码配置方式
pom.xml中加入
com.baomidou
mybatis-plus-generator
3.5.2
代码见:
generator.MyMbatisPlusGenerator
#### 参考文献
[从零开始学Spring Boot](http://412887952-qq-com.iteye.com/blog/2405716/)
[thymeleaf使用详解](https://www.cnblogs.com/ityouknow/p/5833560.html)
[redis命令参考](http://redisdoc.com/#)