1.配置maven
File->Settings
创建Maven工程
2.配置pom.xml文件
配置SpringBoot相关依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>SpringBoot01</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<!--简化部署-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3.写启动器(注意启动器所在位置)
主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器
ackage com.qyc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 2020/4/3 - 0:47
*/
@SpringBootApplication
public class Star {
public static void main(String[] args) {
SpringApplication.run(Star.class,args);
}
}
以后直接运行这个main就相当于启动了fu'wu'qi
4.简单的例子helloWord
写controller
package com.qyc.com.qyc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* 2020/4/3 - 0:50
*/
@Controller
@RequestMapping("/test")
public class Controller01 {
@ResponseBody //写出去
@RequestMapping("/hello")
public String test01(){
return "你好SpringBoot";
}
}
输入链接http://localhost:8080/test/hello
5.使用Spring initializr初始化器创建SpringBoot项目
目录结构
6.配置文件
SpringBoot使用一个全局的配置文件,配置文件名是固定的;
- application.properties
- application.yml
application.yml
people:
name: qyc
age: 21
student:
name: 2017011418
date: 2020/4/4
list: qyc,ssg,!!
map: {qyc: 123,ssg: 456}
- 实体类不能有构造方法,否则注入不进去
@Component //放入容器
@ConfigurationProperties(prefix = "people") //将配置文件中配置的每一个属性的值,映射到这个组件中
public class People {
private String name;
private Integer age;
private Student student;
public String getName() {
return name;
}
test
@RestController //@ResponseBody + @Controller
@RequestMapping("hello")
public class Controller01 {
@Autowired
private People people;
@RequestMapping("test01")
public String test01(){
System.out.println(people.toString());
return "你好SpringBoot Initializer";
}
}
People{name='qyc', age=21, student=Student{name='2017011418', date=Sat Apr 04 00:00:00 CST 2020, list=[qyc, ssg, !!], map={qyc=123, ssg=456}}}
@PropertySource
- 加载指定配置文件
- 将配置文件中配置的每一个属性的值,映射到这个组件中
该注解默认解析.properties格式文件,如果想解析yml文件就需要自己加一个类
yml格式
package com.springbootdemo;
import java.io.IOException;
import java.util.Optional;
import java.util.Properties;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;
/**
* 2020/4/4 - 2:18
*/
public class Yml extends DefaultPropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource)
throws IOException {
String sourceName = Optional.ofNullable(name).orElse(resource.getResource().getFilename());
if (!resource.getResource().exists()) {
// return an empty Properties
return new PropertiesPropertySource(sourceName, new Properties());
} else if (sourceName.endsWith(".yml") || sourceName.endsWith(".yaml")) {
Properties propertiesFromYaml = loadYaml(resource);
return new PropertiesPropertySource(sourceName, propertiesFromYaml);
} else {
return super.createPropertySource(name, resource);
}
}
/**
* load yaml file to properties
*
* @param resource
* @return
* @throws IOException
*/
private Properties loadYaml(EncodedResource resource) throws IOException {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(resource.getResource());
factory.afterPropertiesSet();
return factory.getObject();
}
}
properties格式
@PropertySource(value = {"classpath:people.properties"})
People{name='强月城', age=21, student=Student{name='qyc', date=null, list=null, map=null}}
配置文件加载顺序
springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件
- file:./config/
- file:./
- classpath:/config/
- classpath:/
优先级由高到底,高优先级的配置会覆盖低优先级的配置;
SpringBoot会从这四个位置全部加载主配置文件;互补配置
SpringBoot精髓: 如何使用SpringBoot
- SpringBoot启动会加载大量的自动配置类
- 我们看我们需要的功能有没有SpringBoot默认写好的自动配置类;
- 我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件有,我们就不需要再来配置了)
- 给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们就可以在配置文件中指定这些属性的值;
7.日志 使用手册
基于 框架: SLF4J + 实现:Logback
安装插件 Lombok
作用:可以使用@Slf4j 标签来替代
Logger logger = LoggerFactory.getLogger(Controller.class);
s
添加依赖
<!--日志-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<!--lombok插件 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.16</version>
</dependency>
配置application.properties文件
#配置记录级别 trace debug info warn error
logging.level.com.springbootdemo=debug
#存放日志路径 名默认为 spring.log
logging.file.path=logInfo
测试类
package com.springbootdemo.controller;
import com.springbootdemo.bean.People;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**
* 2020/4/3 - 1:37
*/
@RestController //@ResponseBody + @Controller
@RequestMapping("hello")
@Slf4j
public class Controller01 {
@Autowired
private People people;
// Logger logger = LoggerFactory.getLogger(Controller.class);
@RequestMapping("test01")
public String test01(){
log.debug("debug{}",people);
// logger .info("info{}",people);
// logger .debug("debug{}",people);
log.debug("debug{}",people);
log.info("info{}",people);
return "你好SpringBoot Initializer";
}
}
8.SpringBoot对静态资源的映射规则
- webjars:以jar包的方式引入静态资源
- "classpath:/META-INF/resources/",
- "classpath:/resources/",
- "classpath:/static/",
- "classpath:/public/"
- "/":当前项目的根路径
- 欢迎页: 静态资源文件夹下的所有index.html页面;被"/**"映射
- 所有的 **/favicon.ico 都是在静态资源文件下找 图标
9.引入Thymeleaf
总结:thymeleaf注意路径 @/ 包括static 和 template 要把除了前面俩个的路径写全
启动器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
把HTML页面放在classpath:/templates/,thymeleaf就能自动渲染
@RequestMapping("/test02")
public String test02(){
return "success";
}
注意标签要用 @Controller
Thymeleaf语法
命名空间:
<html lang="en" xmlns:th="http://www.thymeleaf.org">
-
th:text;改变当前元素里面的文本内容;
-
th:任意html属性;来替换原生属性的值
-
${...}:获取变量值
-
*{...}:选择表达式:和${}在功能上是一样
<div th:object="${session.user}"> <p>Name: <span th:text="*{firstName}">
- #{...}:获取国际化内容
-
@{...}:定义URL
-
~{...}:片段引用表达式 <div th:insert="~{commons :: main}">...</div>
循环
iterStat称作状态变量,属性有:
index:当前迭代对象的index(从0开始计算)
count: 当前迭代对象的index(从1开始计算)
size:被迭代对象的大小
current:当前迭代变量
even/odd:布尔值,当前循环是否是偶数/奇数(从0开始计算)
first:布尔值,当前循环是否是第一个
last:布尔值,当前循环是否是最后一个
简单实例:
@RequestMapping("/test02")
public String test02(Map<String,Object> map){
map.put("name","强月城");
People people = new People("强月城",18);
map.put("user",people);
List list = new ArrayList();
list.add("你好");
list.add("SpringBoot");
list.add("Thymeleaf");
map.put("list",list);
return "success";
}
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>成功</h1>
<div th:text="${name}">123</div>
<div >
<span th:text="${user.getName()}"></span>
<span th:text="${user.getAge()}"></span>
<span th:text="${uses}" th:each="uses:${list}">
</span>
</div>
</body>
</html>
10.SpringMVC
SpringBoot自动配置好了SpringMVC
可以编写配置类(@Configuration) 进行扩展
@Configuration
public class Config implements WebMvcConfigurer {
@Override //页面跳转
protected void addViewControllers(ViewControllerRegistry registry) {
// super.addViewControllers(registry);
registry.addViewController("/test03").setViewName("succ");
}
}
国际化
配置
#国际化
spring.messages.basename=i18n.login
目录结构
设置
页面调用 #{ }
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>Signin Template for Bootstrap</title>
<!-- Bootstrap core CSS -->
<link href="/webjars/bootstrap/4.0.0/dist/css/bootstrap.css" th:href="@{/asserts/css/bootstrap.min.css}" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="../static/asserts/css/signin.css" th:href="@{/asserts/css/signin.css}" rel="stylesheet">
</head>
<!-- <script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>-->
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<!-- <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>-->
<body class="text-center">
<form class="form-signin" action="/login" method="post">
<img class="mb-4" src="/asserts/img/bootstrap-solid.svg" alt="" width="72" height="72">
<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>
<p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
<label class="sr-only" th:text="#{login.username}">Username</label>
<input type="text" name="username" class="form-control" placeholder="Username" th:placeholder="#{login.username}" required="" autofocus="">
<label class="sr-only" th:text="#{login.password}">Password</label>
<input type="password" name="password" class="form-control" placeholder="Password" th:placeholder="#{login.password}" required="">
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me" size="10"> [[#{login.remember}]]
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.submit}">Sign in</button>
<p class="mt-5 mb-3 text-muted">© 2017-2018</p>
<a class="btn btn-sm" th:href="@{/index(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index(l='en_US')}">English</a>
</form>
</body>
</html>
编写MyLocaleResolver 类
package com.springbootdemo.component;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.LocaleResolver;
import org.thymeleaf.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
import java.util.Map;
/**
* @author qyc
* @time 2020/4/6 - 20:53
*/
@Slf4j
public class MyLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
String ss = request.getParameter("l");
Locale local = Locale.getDefault();
System.out.println(ss);
if(!StringUtils.isEmpty(ss)){
String s[] = ss.split("_");
local = new Locale(s[0],s[1]);
}
return local;
}
@Override
public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
}
}
注册拦截器 在
@Configuration
public class Config implements WebMvcConfigurer {
// 注册拦截器
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
设置拦截器
编写拦截器类
package com.springbootdemo.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author qyc
* @time 2020/4/6 - 17:27
*/
//拦截器
public class UserInterceptor implements HandlerInterceptor {
//ctrl + o
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String username = (String) request.getSession().getAttribute("user");
if(username!=null){
return true;
}
System.out.println("进入过滤器");
try {
response.sendRedirect("/index");
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
添加拦截器
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new UserInterceptor()).addPathPatterns("/**").excludePathPatterns("/index","/","/login");
// super.addInterceptors(registry);
}
注意:SpringBoot要经过控制器才可以访问静态资源,所以必要时要写映射
protected void addViewControllers(ViewControllerRegistry registry) {
// super.addViewControllers(registry);
// registry.addViewController("/test03").setViewName("succ");
registry.addViewController("/").setViewName("index");
registry.addViewController("/index").setViewName("index");
registry.addViewController("/dashboards.html").setViewName("/page/dashboard");
// registry.addViewController("/login").setViewName("login");
}
抽取公共页面
<div th:fragment="copy">
© 2011 The Good Thymes Virtual Grocery
</div>
引入公共片段
<div th:insert="~{footer :: copy}"></div>
- th:insert:将公共片段整个插入到声明引入的元素中
- th:replace:将声明引入的元素替换为公共片段
- th:include:将被引入的片段的内容包含进这个标签中
<div th:insert="footer :: copy"></div>
<div th:replace="footer :: copy"></div>
<div th:include="footer :: copy"></div>
注意:不是根目录下要加 /目录
整合MyBatis
基础整合
1. 添加starter
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
<scope>runtime</scope>
</dependency>
2.配置 application.yml
spring:
datasource:
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/student
type: com.alibaba.druid.pool.DruidDataSource
jpa:
show-sql: true
mybatis:
# 指定全局配置文件的位置
config-location: classpath:MyBatis/myBatisCfg.xml
# 指定sql映射文件的位置
mapper-locations: classpath:MyBatis/mapper/*.xml
MyBatis配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 下划线转驼峰-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!-- 分页-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
</plugin>
</plugins>
<!-- 整合细节
1. 要在启动类上添加 @MapperScan("com.springbootdemo02.mvc.mapper") 开启扫描
2. sql语句表名不能加“ ”
3. 版本要求不能太高
4. @Mapper
@Repository 消除警告
-->
</configuration>
启动类要加扫描@MapperScan("包")
package com.springbootdemo02;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.annotation.MapperScans;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication //开启自动配置
//扫描当前包及其子包
@MapperScan("com.springbootdemo02.mvc.mapper")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Mapper接口
@Mapper
@Repository
public interface StudentMapper {
List<Student> selectAll();
Student selectID(String num);
List<People> select();
}
Mapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.springbootdemo02.mvc.mapper.StudentMapper">
<select id="selectAll" resultType="com.springbootdemo02.bean.Student">
select * from classtable
</select>
<select id="selectID" resultType="com.springbootdemo02.bean.Student">
select * from classtable where classid = #{num }
</select>
<select id="select" resultType="com.springbootdemo02.bean1.People">
select * from people
</select>
</mapper>
整合JPA
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
实体类
@Entity
@Table(name = "people")
public class People {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "list_name")
private String list_name;
public People() {
}
继承JpaRepository
package com.springbootdemo02.mvc.repository;
import com.springbootdemo02.bean.People;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* @author qyc
* @time 2020/4/10 - 12:09
*/
public interface PeopleRepository extends JpaRepository<People,Integer> {
}
service
@Service
public class PeopleService {
@Autowired
private PeopleRepository repository;
// @Autowired
// private StudentMapper studentMapper;
public Optional<People> selectId(int id){
return repository.findById(id);
}
public List<People> selectAll(){
return repository.findAll();
}
public void insertPeople(People people){
repository.save(people);
}
public void delete(int id){
repository.deleteById(id);
}
public void update(People people){
repository.saveAndFlush(people);
}
整合Redis
简单实例
添加pom
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置application
#配置Redis服务器主机地址
spring.redis.host=192.168.32.128
自动注入模板
package com.springbootdemo02.redis;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
/**
* @author qyc
* @time 2020/4/13 - 20:14
*/
@Service
public class RedisDemo {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private StringRedisTemplate stringRedisTemplate;
public void test01(){
stringRedisTemplate.opsForValue().append("qyc","我是强月城,你好redis");
}
}
整合Jackson
1.对象转jackson
导依赖
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
不能有自定义构造方法
@JsonIgnoreProperties(ignoreUnknown = true)
public class People {
private int id;
private String list_name;
// public People(int id, String list_name) {
// this.id = id;
// this.list_name = list_name;
// }
People people = new People();
people.setId(1);
people.setList_name("强月城");
ObjectMapper objectMapper = new ObjectMapper();
String jacksons = objectMapper.writeValueAsString(people);
System.out.println(jacksons);
People people1 = objectMapper.readValue(jacksons, People.class);
System.out.println(people1);
2.配置Jackson模板 (不是最重要的)2.0版本以后就要改写了 下面代码仅供参考
@Configuration
public class JacksonCfg {
@Bean
public RedisTemplate<Object,Object> jsonredisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisTemplate<Object,Object> template = new RedisTemplate<Object,Object>();
template.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer<Object> ser = new Jackson2JsonRedisSerializer<Object>(Object.class);
template.setDefaultSerializer(ser);
return template;
}
}
@Autowired
private RedisTemplate<Object,Object> jsonredisTemplate;
public void test01() throws JsonProcessingException {
//转json
People people = new People(1,"强月城");
jsonredisTemplate.opsForValue().set("qyc01",people);
}
}
Redis整合缓存
主方法加 @EnableCaching 开启缓存
@SpringBootApplication //开启自动配置
//扫描当前包及其子包
@MapperScan("com.springbootdemo02.mvc.mapper")
@EnableCaching
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
配置RedisTemplate和RedisCacheManage 目的是为了json与对象的相互转换
@Configuration
public class JacksonCfg {
@Bean
public RedisTemplate<Object, Object> empRedisTemplate(
RedisConnectionFactory redisConnectionFactory){
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
// 转换 格式
Jackson2JsonRedisSerializer<Object> employeeJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
template.setDefaultSerializer(employeeJackson2JsonRedisSerializer);
return template;
}
/**
* 基于SpringBoot2 对 RedisCacheManager 的自定义配置
* @param redisConnectionFactory
* @return
*/
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
//初始化一个RedisCacheWriter
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
//设置CacheManager的值序列化方式为json序列化
RedisSerializer<Object> jsonSerializer = new GenericJackson2JsonRedisSerializer();
RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair.fromSerializer(jsonSerializer);
RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(pair);
//设置默认超过时期是1天
defaultCacheConfig.entryTtl(Duration.ofDays(1));
//初始化RedisCacheManager
return new RedisCacheManager(redisCacheWriter, defaultCacheConfig);
}
}
service 添加注解
@Cacheable(cacheNames = "peopleASP")
public Optional<People> selectid(int id){
Optional<People> people = repository.findById(id);
return people;
}
@Cacheable :将返回值缓存
@CachePut : 既调用方法,又更新缓存数据;
* 修改了数据库的某个数据,同时更新缓存;
* 运行时机:
* 1、先调用目标方法
* 2、将目标方法的结果缓存起来
* @param employee
* @return
*
*
@CacheEvict : 缓存清除
* key : 指定要清除的数据
* allEntries = true : 指定要清除所有的数据
* beforeInvocation = false : 缓存的清除是否再方法之前执行
* 默认代表缓存清除操作是在方法执行后执行 ; 如果出现异常缓存就不会清除
* beforeInvocation = true : 代表清除缓存操作是在方法运行之前执行,无论方法是否出现异常,缓存都清除
全局Session会话管理
导依赖
<!-- RedisSession全局配置-->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
配置RedisSessionManager(默认已经开启,不配置也可以)
@Configuration
@EnableRedisHttpSession //开启全局session会话管理
public class RedisSessionManager {
}
controller 简单测试
@RequestMapping("/session/{id}")
public String sessionTest01(@PathVariable("id") String sid, HttpServletRequest request, HttpServletResponse response){
Student student = new Student("2017011418","qyc");
Student s = (Student) request.getSession().getAttribute(sid);
if(null==s){
request.getSession().setAttribute(sid,student);
System.out.println("注册成功");
}else {
System.out.println("登陆成功"+s);
}
return "success";
}
}
注意:Bean要支持序列化 否则从Redis读取不出来
public class Student implements Serializable {
private String classid;
private String classname;
构造方法要齐全 无参+有参
整合Rabbitmq
https://blog.csdn.net/qq_41835813/article/details/105535055
整合ElasticSearch 待续
异步
开启异步:@EnableAsync
注释:@Async
//异步
@Async
public void hello(){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("hello");
}
定时任务
@EnableScheduling//开启定时任务
//定时
//定时任务 秒 分 小时 日期 月 星期 自动运行
@Scheduled(cron = "30 4 19 17 4 *")
public void time(){
System.out.println("定时任务开启");
}
发送邮件
配置文件
spring.mail.username=1227694865@qq.com
spring.mail.password=sjiowpuzuzqabach
spring.mail.host=smtp.qq.com
spring.mail.properties.mail.smtp.ssl.enable=true
service
//emal
@Autowired
JavaMailSenderImpl sender;
public void contextLoads(String mail){
SimpleMailMessage message = new SimpleMailMessage();
message.setSubject("通知");
message.setText("测试邮件");
message.setTo(mail+"@qq.com");
message.setFrom("1227694865@qq.com");
sender.send(message);
System.out.println("发送成功");
}
复杂邮件
//复杂消息文件
public void mine(String mail){
MimeMessage mimeMessage = sender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true);
helper.setSubject("通知1");
helper.setText("<b style='color:red'>测试邮件</d>",true);
helper.setTo(mail+"@qq.com");
helper.setFrom("1227694865@qq.com");
helper.addAttachment("123.jpg",new File("H:\\图片\\新建文件夹\\123.jpg"));
sender.send(mimeMessage);
} catch (MessagingException e) {
e.printStackTrace();
}
}
安全SpringSecurity
pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
UserInfo 现在没用,等自定义认证的时候才有用
@Entity
@Table(name="usertable")
public class UserInfo {
@Id
private int id;
private String name;
private String password;
private String role;
配置
@EnableWebSecurity
public class Securitycfg extends WebSecurityConfigurerAdapter {
//定制请求授权规则
@Override
protected void configure(HttpSecurity http) throws Exception {
// super.configure(http);
http.authorizeRequests().antMatchers("/home").permitAll().
antMatchers("/vip1/**").hasAnyRole("vip1").
antMatchers("/vip2/**").hasAnyRole("vip2").
antMatchers("/vip3/**").hasAnyRole("vip3");
http.formLogin(); //开启默认登录界面
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// super.configure(auth);
auth.inMemoryAuthentication().passwordEncoder(new MyPassword()).withUser("py").
password("123").roles("vip2");
}
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
现在只是实现了简单的登录认证,没有和数据库连接,待续
整合shiro
https://blog.csdn.net/qq_41835813/article/details/105623538
热部署
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>