SPRINGBOOT高级教程知识

**************************************************************************************************************************************************************

1、Springboot与缓存
【1】访问量大、临时性数据
【2】JSR107(用的少)、缓存抽象

**************************************************************************************************************************************************************

2、Spring缓存抽象
【1】CacheManager与Cache获取
【2】@Cacheable、@CacheEvict、@CachePut、@EableCaching、keyGenerator、serialize

**************************************************************************************************************************************************************

3、缓存-基本环境搭建
【1】BigController 
package com.day.study.controller;
import com.day.study.mapper.BigMapper;
import com.day.study.pojo.Employee;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class BigController {@ResourceBigMapper bigMapper;@GetMapping("/employee")public Employee selectEmployee(Employee employee) {return bigMapper.selectEmployeeById(employee);}
}

**************************************************************************************************************************************************************

4、Cacheable初体验
【1】开启基于注解的缓存 @EnableCaching在SpringBoot上面;
【2】标注缓存注解即可
【3】如果没有缓存,都是每次都从数据库拿到
# log
logging.level.com.day.study.mapper=debug
【4】标记可以用缓存的Mapper中的方法
package com.day.study.mapper;
import com.day.study.pojo.Employee;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.cache.annotation.Cacheable;
@Mapper
public interface BigMapper {// 查询@Cacheable(cacheNames = "employee")Employee selectEmployeeById(@Param("employee") Employee employee);// 添加void insertEmployee(@Param("employee") Employee employee);// 修改void updateEmployee(@Param("employee") Employee employee);// 删除void deleteEmployee(@Param("employee") Employee employee);
}
【5】Controller里也要同步
package com.day.study.controller;
import com.day.study.mapper.BigMapper;
import com.day.study.pojo.Employee;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class BigController {@ResourceBigMapper bigMapper;@Cacheable(cacheNames = "employee")@GetMapping("/employee")public Employee selectEmployee(Employee employee) {return bigMapper.selectEmployeeById(employee);}
}
【6】CacheManager 缓存管理器、Condition在满足条件的情况下才缓存
【7】还有异步等模式

**************************************************************************************************************************************************************

5、缓存工作原理与执行流程
【1】自动配置类、缓存配置类
【2】注册了一个缓存管理器
【3】生成Key的策略、@Cacheable标注的方法执行之前会先看缓存中是否存在,按照key去缓存查询
【4】核心:
(1)CacheManager 按照名字得到Cache组件
(2)Key是使用SimpleKeyGenerator生成的
(3)根据Key看缓存是否存在,不存在查,存在用

**************************************************************************************************************************************************************

6、@Cacheable别的属性
【1】cacheNames和value一样,可以指定多个名字
【2】key="#root.methodName+'['+#id+']'"
【3】condition 在某种条件满足的时候才缓存,如="#a0>1"
【4】unless="#a0==2" 如果第一个参数的值为2则不缓存

**************************************************************************************************************************************************************

7、缓存CachePut概述
【1】既调用方法,又更新缓存数据:典型场景-修改数据库的某个数据,同时更新缓存
【2】缓存和CachePut更新缓存的ID必须一致,不然就出现不一致了。(没有Redis好用!!!!!!!!!!!!!!!!!!!!)
package com.day.study.controller;
import com.day.study.mapper.BigMapper;
import com.day.study.pojo.Employee;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class BigController {@ResourceBigMapper bigMapper;@Cacheable(cacheNames = "employee", key = "#employee.id")@GetMapping("/selectEmployee")public Employee selectEmployee(Employee employee) {return bigMapper.selectEmployeeById(employee);}@CachePut(cacheNames = "employee", key = "#employee.id")@GetMapping("/updateEmployee")public Employee updateEmployee(Employee employee) {bigMapper.updateEmployee(employee);return employee;}
}

**************************************************************************************************************************************************************

8、缓存CacheEvict
【1】缓存删除
【2】删除后就回重新从数据库查询,不如Redis@ResourceBigMapper bigMapper;@Cacheable(cacheNames = "employee", key = "#employee.id")@GetMapping("/selectEmployee")public Employee selectEmployee(Employee employee) {return bigMapper.selectEmployeeById(employee);}@CachePut(cacheNames = "employee", key = "#employee.id")@GetMapping("/updateEmployee")public Employee updateEmployee(Employee employee) {bigMapper.updateEmployee(employee);return employee;}@CacheEvict(cacheNames = "employee", key = "#employee.id")@GetMapping("/deleteEmployee")public Employee deleteEmployee(Employee employee) {System.out.println("执行删除...");//bigMapper.deleteEmployee(employee);return employee;}

**************************************************************************************************************************************************************

9、缓存Caching与CacheConfig
【1】复杂的缓存规则组合
【2】CacheConfig在Controller上面标记,这样不用每一个都单独标记了

**************************************************************************************************************************************************************

10、Redis环境配置
【1】缓存中间件redis、memcached、ehcache
【2】整合redis作为缓存,就以阿里云的redis为例(用docker也可以安装)
【3】用RDM连接后可以界面化操作redis
【4】执行一些基本的控制台操作命令

**************************************************************************************************************************************************************

11、RedisTemplate与序列化机制
【1】redis的startes<!--redis--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>
【2】数据类型字符串String、List 列表、Set集合、Hash散列、Zset集合
【3】properties配置
# redis
spring.redis.host=wdfgdzx.top
spring.redis.port=6379
spring.redis.password=s19911009!
spring.redis.database=0
【4】测试相关方法
(1)保存对象需要序列化
(2)以JSON保存数据
(3)存对象都是二进制,来改变其序列化规则
package com.day.study.config;import com.day.study.pojo.Employee;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;@Configuration
public class MyRedisConfig {@Beanpublic RedisTemplate<Object, Employee> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws Exception {RedisTemplate<Object, Employee> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(redisConnectionFactory);Jackson2JsonRedisSerializer<Employee> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Employee.class);redisTemplate.setDefaultSerializer(jackson2JsonRedisSerializer);return redisTemplate;}
}
(4)方法
package com.day.study.controller;
import com.day.study.mapper.BigMapper;
import com.day.study.pojo.Employee;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class Controller {@AutowiredStringRedisTemplate stringRedisTemplate;@AutowiredRedisTemplate<Object, Employee> redisTemplate;@AutowiredBigMapper bigMapper;@Testpublic void contextLoads() {//stringRedisTemplate.opsForValue().append("msg", "Hello");//System.out.println(stringRedisTemplate.opsForValue().get("msg"));//stringRedisTemplate.opsForList().leftPush("myList", "1");//stringRedisTemplate.opsForList().leftPush("myList", "2");Employee employee = new Employee();employee.setId(1);employee.setEmail("wdfgdzx@163.com");redisTemplate.opsForValue().set("emp01", employee);}
}

**************************************************************************************************************************************************************

12、缓存-自定义CacheManager
【1】被RedisCacheManager接管了
【2】技术更新太快了,老师一堂课不如网上百度一下
package com.day.study.config;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
@Configuration
public class MyRedisConfig {@Beanpublic RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {CacheProperties.Redis redisProperties = cacheProperties.getRedis();RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));//还有另外一种写法if (redisProperties.getTimeToLive() != null) {config = config.entryTtl(redisProperties.getTimeToLive());}if (redisProperties.getKeyPrefix() != null) {config = config.prefixKeysWith(redisProperties.getKeyPrefix());}if (!redisProperties.isCacheNullValues()) {config = config.disableCachingNullValues();}if (!redisProperties.isUseKeyPrefix()) {config = config.disableKeyPrefix();}return config;}
}
【3】名称也可以自定义  @Cacheable(value = "files", key = "'selfDefineName'")
【4】这个MyRedisConfig 就比较实用了,适用多个类
package com.day.study.controller;
import com.day.study.mapper.BigMapper;
import com.day.study.pojo.Department;
import com.day.study.pojo.Employee;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class BigController {@ResourceBigMapper bigMapper;@Cacheable(cacheNames = "employee", key = "#employee.id")@GetMapping("/selectEmployee")public Employee selectEmployee(Employee employee) {return bigMapper.selectEmployeeById(employee);}@CachePut(cacheNames = "employee", key = "#employee.id")@GetMapping("/updateEmployee")public Employee updateEmployee(Employee employee) {bigMapper.updateEmployee(employee);return employee;}@CacheEvict(cacheNames = "employee", key = "#employee.id")@GetMapping("/deleteEmployee")public Employee deleteEmployee(Employee employee) {System.out.println("执行删除...");//bigMapper.deleteEmployee(employee);return employee;}@Cacheable(cacheNames = "department", key = "'department'")@GetMapping("/selectDepartment")public Department department(Department department) {return bigMapper.selectDepartmentById(department);}
}
【5】也可以拿到缓存模板直接使用
@Resource
private StringRedisTemplate stringRedisTemplate;

**************************************************************************************************************************************************************

13、消息中间件概述
【1】用户注册—>发邮件—>发短信怎么优化处理?
(1)写数据库后:多线程边发邮件,边发短信
(2)消息队列,写数据库后,写进消息队列(消息队列再发短信、发邮件)
【2】应用解耦:订单 VS 库存
(1)订单、库存单独抽取出来
(2)订单消费、库存订阅消息队列
【3】流量削峰
用户请求—>消息队列(1W+)—>秒杀业务处理
【4】消息服务:消息代理(服务器)、目的地
(1)目的地包括:队列(Queue)-点对点通信、主体(Topic)-发布订阅模式
(2)点对点 A 发给队列—>队列—>B B从队列收
(3)发布订阅:A发布到主题里,B C D同时监听收到
【5】JMS:JAVA MESSAGE SERVICE;Java消息服务
(1)基于JVM消息代理规范,如ActiveMQ、HornetMQ就是JMS的实现
【6】AMQP高级消息队列协议,兼容JMS,大名鼎鼎的RabbitMQ就是AMQP的实现
【7】Springboot的配置
(1)RabbitAutoConfiguration

**************************************************************************************************************************************************************

14、RabbitMQ概述
【1】RMQ:核实概念-Message(消息头、消息体)
(1)路由键、优先权、是否持久化存储
(2)生产者:消息生产者、发布给交换器
(3)交换器:四种类型direct点对点;fanout、topic、headers实现发布订阅模型
(4)消息队列:用来保存消息的
(5)绑定:交换器与队列之间的绑定关系
(6)网络连接:如TCP连接
(7)Channel:信道,一个TCP连接可以开多个信道
(8)消费者
(9)虚拟主机
(10)Broke消息代理,就是服务器

**************************************************************************************************************************************************************

15、RMQ的核心运行机制
【1】增加了Exchange(四种类型)与Binding的角色
(1)direct 直连型
(2)Fanout Exchange,接收到消息后,会分发给它自己的所有队列,速度最快
(3)Topic Exchange,支持模糊匹配(感觉不实用)

**************************************************************************************************************************************************************

16、RMQ安装测试
【1】docker pull rabbitmq:3-management
【2】docker run -d -p 5672:5672 -p 15672:15672 --name my_rabbitmq 镜像ID
【3】访问http://192.168.0.105:15672/
【4】账号+密码 guest guest
【5】添加三个交换器
exchange.direct     direct	D		
exchange.fanout    fanout	D		
exchange.topick     topic	D	
【6】建立四个队列
wdfgdzx
wdfgdzx.news
wdfgdzx.emps
it.news
【7】绑定交互器与队列
【8】可以在界面测试不同模式发送消息,消息的接受情况

**************************************************************************************************************************************************************

17、RabbitTemplate发送接受消息与序列化机制
【1】引入MAVEN依赖<!--amqp-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
【2】RabbitTemplate类似于RedisTemplate
package com.day.study.controller;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@RunWith(SpringRunner.class)
@SpringBootTest
public class Controller {@AutowiredRabbitTemplate rabbitTemplate;@Testpublic void contextLoads() {// rabbitTemplate.send(exchange,routeKey,message);// rabbitTemplate.convertAndSend(exchange, routeKey, object);Map<String, Object> map = new HashMap<>();map.put("msg", "这是第一个消息");map.put("data", Arrays.asList("Hello", 123, false));rabbitTemplate.convertAndSend("exchange.direct","wdfgdzx.news",map);// 对象默认被序列化以后发送出去}@Testpublic void receive() {// 接受数据Object object = rabbitTemplate.receiveAndConvert("wdfgdzx.news");System.out.println(object.getClass());System.out.println(object);}
}
【3】配置存储JSON
package com.day.study.config;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyRMQConfig {@Beanpublic MessageConverter messageConverter() {return new Jackson2JsonMessageConverter();}
}
【4】其他模式只需要指定交换器和队列就行了,听君一席话,胜过单独学RMQ,使用主义最重要!!!

**************************************************************************************************************************************************************

18、消息监听@RabbitLister与@EnableRabbit
【1】@RabbitListener(queues = "wdfgdzx.news")+@EnableRabbit // 开启基于注解RMQ
开启自动监听,并实时接受消息
【2】Service
package com.day.study.service;import com.day.study.pojo.Employee;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;@Service
public class EmployeeService {@RabbitListener(queues = "wdfgdzx.news")public void receive(Employee employee) {System.out.println("收到消息..." + employee);}@RabbitListener(queues = "wdfgdzx.news")public void receive02(Message message) {System.out.println("收到消息..." + message.getMessageProperties() + "..." + message.getBody());}
}
【3】启动类
package com.day.study;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@EnableCaching
@SpringBootApplication
@MapperScan("com.day.study.mapper")
@EnableRabbit // 开启基于注解RMQ
public class SpringBoot {public static void main(String[] args) {SpringApplication.run(SpringBoot.class, args);}
}
【4】测试控制器
package com.day.study.controller;
import com.day.study.pojo.Employee;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@RunWith(SpringRunner.class)
@SpringBootTest
public class Controller {@AutowiredRabbitTemplate rabbitTemplate;@Testpublic void contextLoads() {// rabbitTemplate.send(exchange,routeKey,message);// rabbitTemplate.convertAndSend(exchange, routeKey, object);Employee employee = new Employee();employee.setId(1);employee.setName("陈翔");employee.setEmail("cx@163.com");rabbitTemplate.convertAndSend("exchange.fanout","wdfgdzx.news",employee);// 对象默认被序列化以后发送出去}@Testpublic void receive() {// 接受数据Object object = rabbitTemplate.receiveAndConvert("wdfgdzx.news");System.out.println(object.getClass());System.out.println(object);}
}

**************************************************************************************************************************************************************

19、AmqpAdmin管理组件的使用
【1】帮助我们创建删除交换器和队列@AutowiredAmqpAdmin amqpAdmin;@Testpublic void createExchange() {// 交换器amqpAdmin.declareExchange(new DirectExchange("amqpadmin.exchange"));System.out.println("创建完成");// 队列amqpAdmin.declareQueue(new Queue("amqpadmin.queue", true));System.out.println("创建完成");// 绑定关系amqpAdmin.declareBinding(new Binding("amqpadmin.queue",Binding.DestinationType.QUEUE,"amqpadmin.exchange","amqp.Hello", null));System.out.println("绑定成功");}

**************************************************************************************************************************************************************

20、Elasticsearch概述与安装
【1】ElasticSearch是全文搜索引擎的首选
【2】环境搭建docker pull elasticsearch
【3】docker run -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -d -p 9200:9200 -p 9300:9300 --name es 镜像ID
【4】docker rm -f $(docker ps -a -q)
【5】访问http://192.168.0.105:9200/ 能看到JSON说明就安装成功了

**************************************************************************************************************************************************************

21、ES入门
【1】JSON代表数据对象
【2】索引(库)、类型(表)、文档(记录)、属性(列)
【3】PUT /megacorp/employee/1
{
"fristName":"陈",
"lastName":"翔",
"age":25,
"about":"I love china",
"interests":["ball","play"]
}
【4】用postman发送请求,注意是PUT方式http://192.168.0.105:9200/megacorp/employee/1
(1)然后body-raw-JSON
(2)复制粘贴数据,发起请求即可
{
"fristName":"陈",
"lastName":"翔",
"age":25,
"about":"I love china",
"interests":["ball","play"]
}
【5】寻找数据 GET http://192.168.0.105:9200/megacorp/employee/3
【6】其他操作
(1)HEAD请求,看是否存在,存在200,不存在404 http://192.168.0.105:9200/megacorp/employee/3
(2)DELETE删除请求http://192.168.0.105:9200/megacorp/employee/3
(3)更新也是用PUT,会看到_version有变化
【7】GET http://192.168.0.105:9200/megacorp/employee/_search 查所有
【8】按条件找
http://192.168.0.105:9200/megacorp/employee/_search?q=lastName:球
【9】用JSON规则匹配查找
(1)POST  http://192.168.0.105:9200/megacorp/employee/_search
(2)JSON过滤规则
{"query":{"match":{"lastName":"头"}}
}
(3)其他过滤规则
{"query":{"match":{"about":"china"}}
}
(4)找到并高亮
{"query":{"match":{"about":"china"}},"highlight":{"fields":{"about":{}}}
}

**************************************************************************************************************************************************************

22、Springboot整合Jest操作ES
【1】引入依赖<!--elasticsearch-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
【2】两种技术交互Jest与SpringData ElasticSearch
(1)Jest 需要导入工具包
(2)我觉得还是用官方的SpringData操作

**************************************************************************************************************************************************************

23、整合SpringDataElasticSearch
【1】注意版本适配关系
【2】如果不适配,需要将es版本调成一致(可以从maven依赖查看版本)
(1)docker pull elasticsearch:6.4.3
(2)/usr/share/elasticsearch/config
(3)docker run -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -d -p 9200:9200 -p 9300:9300 --name es  01e5bee1e059
(4)docker rm -f $(docker ps -a -q)
(5)docker exec -it es /bin/bash 进到docker里yum install net-tools,可以用netstat -lnp|grep 9查看端口监听情况
(6)访问http://192.168.0.105:9200/,注意cluster_name对应的值,这个很重要
(7)历经艰险,ES重要配置成功了
【3】解决es与redis的netty-transport版本冲突
public class SpringBoot {public static void main(String[] args) {// 解决es与redis的netty-transport版本冲突System.setProperty("es.set.netty.runtime.available.processors", "false");SpringApplication.run(SpringBoot.class, args);}
}
【4】插入ES数据
@ResourceEmployeeRepository employeeRepository;@RequestMapping("/insertEs")public String insertEs(Employee employee) {employee.setId(110161);employee.setName("陈翔...");employeeRepository.index(employee);return "es 插入成功";}
【5】查询ES数据
http://192.168.0.105:9200/wdfgdzx/employee/_search
【6】还可以通过另一种方式
(1)service里写方法
package com.day.study.service;
import com.day.study.pojo.Employee;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import java.util.List;
public interface EmployeeRepository extends ElasticsearchRepository<Employee, Integer> {public List<Employee> findByEmployeeName(String name);
}
(2)controller写查询@RequestMapping("/selectEs")public List<Employee> selectEs(Employee employee) {List<Employee> employeeList = employeeRepository.findByEmployeeName("陈");return employeeList;}
(3)浏览器查询http://localhost:8080/selectEs
[{"id":110161,"employeeName":"陈翔...","email":null}]

**************************************************************************************************************************************************************

24、Springboot执行任务
【1】异步、定时、发邮件任务
【2】异步类
package com.day.study.service;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class AsyncService {@Async //告诉Spring 这是一个异步方法public void say() throws InterruptedException {Thread.sleep(3000);System.out.println("处理数据中...");}
}
【3】启动类
@EnableAsync // 开启异步注解
【4】Controller
@RequestMapping("/say")public String say() throws InterruptedException {asyncService.say();return "调用成功...";}

**************************************************************************************************************************************************************

25、定时任务
【1】比如每天凌晨,跑前一天的数据
【2】类
package com.day.study.service;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@Service
public class ScheduleService {// 六位表达式@Scheduled(cron = "0 * * * * MON-SAT")  //每整分钟就打印一个Hellopublic void say() {System.out.println("Hello...");}
}
【3】启动类
@EnableScheduling
【4】每分钟都会执行一次方法
【5】具体的写法可以百度

**************************************************************************************************************************************************************

26、邮件任务
【1】依赖
<!--mail-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId>
</dependency>
【2】配置
# mail
spring.mail.host=220.181.15.111
spring.mail.username=wdfgdzx@126.com
spring.mail.password=GAVHJSFHPCUOYMPP
【3】测试发送邮件@AutowiredJavaMailSenderImpl javaMailSender;@org.junit.Testpublic void textMail() {SimpleMailMessage simpleMailMessage = new SimpleMailMessage();//邮件设置simpleMailMessage.setSubject("通知-会议");simpleMailMessage.setText("今晚7:30开会");simpleMailMessage.setTo("wdfgdzx@163.com");simpleMailMessage.setFrom("wdfgdzx@126.com");javaMailSender.send(simpleMailMessage);}@org.junit.Testpublic void textMailTwo() throws Exception {MimeMessage mimeMessage = javaMailSender.createMimeMessage();MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);mimeMessageHelper.setSubject("通知-会议");mimeMessageHelper.setText("<b style='color:red'>今晚7:30开会</b>", true);mimeMessageHelper.setTo("wdfgdzx@163.com");mimeMessageHelper.setFrom("wdfgdzx@126.com");//上传附件mimeMessageHelper.addAttachment("1.jpg", new File("src/main/resources/mapper/BigMapper.xml"));javaMailSender.send(mimeMessage);}

**************************************************************************************************************************************************************

27、Springboot与安全
【1】Spring Security
【2】就是为了实现认证和授权
【3】依赖引入<!--security-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>
【4】引入指定页面thymeleaf<!--thymeleaf--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>
【5】@org.springframework.stereotype.Controller

**************************************************************************************************************************************************************

28、权限控制-注销
【1】配置类
package com.day.study.config;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@EnableWebSecurity //内部带Configuration所以无需再次标注
public class MySecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity httpSecurity) throws Exception {//super.configure(httpSecurity);// 定制请求的授权规则httpSecurity.authorizeRequests().antMatchers("/index").permitAll().antMatchers("/low/**").hasRole("VIP").antMatchers("/high/**").hasRole("H VIP");// 开启自动配置的登录功能httpSecurity.formLogin();// 1、/login来到登录页 2、重定向到error表示登录失败 3、更多详析规则// 效果就是没有权限,就来到登录页面// 开启自动配置的注销功能httpSecurity.logout().logoutSuccessUrl("/index");// 1、会清空session 2、注销成功跳转的页面}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {//super.configure(auth);// 按道理从数据库拿,但是这里演示就存内存auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()).withUser("VIP").password(new BCryptPasswordEncoder().encode("123")).roles("VIP").and().withUser("H VIP").password(new BCryptPasswordEncoder().encode("123")).roles("H VIP");}
}
【2】配置@org.springframework.stereotype.Controller
package com.day.study.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@org.springframework.stereotype.Controller
public class Controller {@RequestMapping("index")public ModelAndView index() {ModelAndView mv = new ModelAndView("index");return mv;}@RequestMapping("low")public ModelAndView low() {ModelAndView mv = new ModelAndView("low");return mv;}@RequestMapping("high")public ModelAndView high() {ModelAndView mv = new ModelAndView("high");return mv;}
}
【3】没有权限看不到,这个就不配置了
(1)界面写的也有点冗余,不如用vue写了

**************************************************************************************************************************************************************

30、定制登录页
【1】就是使用cookie记录用户信息
【2】可以定制Security的登录页面

**************************************************************************************************************************************************************

31、Springboot与分布式
【1】Dubbo/Zookeeper、Springboot/Cloud
【2】注册中心

**************************************************************************************************************************************************************

32、Zookeeper安装
【1】docker rm -f $(docker ps -a -q)
【2】docker pull zookeeper
【3】docker run --name zk -p 2181:2181 --restart always -d 979f6ccbba92
【4】启动成功

**************************************************************************************************************************************************************

33、整合Dubbo与Zookeeper
【1】整合步骤
(1)服务提供者注册到注册中心
(2)引入依赖
(3)配置properties
(4)启动服务

**************************************************************************************************************************************************************

34、SpringCloud的注册中心
【1】是分布式的整体解决方案
【2】服务发现、负载均衡、断路器、服务网关、分布式配置
【3】引依赖<!--eureka server--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId><version>2.1.6.RELEASE</version></dependency><!--eureka client--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId><version>2.1.6.RELEASE</version></dependency>
【4】配置properties
server.port=8083
# 实例的主机名
eureka.instance.hostname=eureka-server
# 不把自己注册
eureka.client.register-with-eureka=false
# 不获取服务注册信息
eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://localhost:8083/eureka/
【5】访问http://localhost:8083可以看到注册中心
【6】provider
server.port=8081
spring.application.name=provider
# 实例的主机名       注册服务时使用IP地址
eureka.instance.prefer-ip-address=true
eureka.client.service-url.defaultZone=http://localhost:8083/eureka/
【7】可以配置多个端口指向注册中心的

**************************************************************************************************************************************************************

36、配置消费者
【1】properties
server.port=8082
spring.application.name=consumer
# 实例的主机名       注册服务时使用IP地址
eureka.instance.prefer-ip-address=true
eureka.client.service-url.defaultZone=http://localhost:8083/eureka/
【2】Controller
package com.day.consumer.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
@RestController
public class ConsumerController {@ResourceRestTemplate restTemplate;@RequestMapping("buyTicket")public String buyTicket(String name) {String getTicketFromServer = restTemplate.getForObject("http://PROVIDER/getTicket", String.class);return name + "购买了" + getTicketFromServer;}
}
【3】卧槽惊艳了,挺好用的,牛批

**************************************************************************************************************************************************************

37、Springboot开发热部署
【1】推荐使用官方的spring-boot-devtools,Ctrl+F9
【2】没必要呀,手动重启不就行了

**************************************************************************************************************************************************************

38、Springboot与监控管理!!!!
【1】运维时重要的功能 spring-boot-starter-actuator
【2】依赖
<!--actuator监控模块--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency>
【3】配置properties
management.endpoints.web.exposure.include=*
management.endpoints.web.base-path=/
management.endpoint.health.show-details=always
management.endpoint.info.enabled=true
【4】访问监控信息
(1)http://localhost:8080/health 健康信息
(2)http://localhost:8080/auditevents 审计事件
(3)http://localhost:8080/beans 组件信息
(4)http://localhost:8080/info 配置文件里的info开头的配置
(5)http://localhost:8080/dump 线程信息
(6)http://localhost:8080/env 当前环境信息
(7)http://localhost:8080/mappings 请求映射信息
(8)http://localhost:8080/metrics 应用的各项指标

**************************************************************************************************************************************************************

39、定制端点
【1】改变端点的ID等信息
【2】开启和关闭某个端点
【3】定制根路径
【4】改变端点对应的端口号

**************************************************************************************************************************************************************

40、定制HealthIndicator
【1】这个监控可以检查不健康的配置
spring.redis.host=localhost<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
【2】访问http://localhost:8080/health,redis的配置不正确
{"status":"DOWN","details":{"diskSpace":{"status":"UP","details":{"total":120032587776,"free":35320840192,"threshold":10485760}},"redis":{"status":"DOWN","details":{"error":"org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to localhost:6379"}}}}
【3】定制化:
(1)实现HealthIndicator接口
(2)名字 XXXHealthIndicator
(3)加入容器中
【4】定制化实例
package com.day.study.health;import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;@Component
public class MyHealthIndicator implements HealthIndicator {@Overridepublic Health health() {// 自定义检查方法// ...// return Health.up(); 代表健康return Health.down().withDetail("msg", "服务异常").build();}
}
【5】访问http://localhost:8080/health 的效果
{"status":"DOWN","details":{"my":{"status":"DOWN","details":{"msg":"服务异常"}},"diskSpace":{"status":"UP","details":{"total":120032587776,"free":35317649408,"threshold":10485760}},"redis":{"status":"DOWN","details":{"error":"org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to localhost:6379"}}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/831675.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【科研技术】华为为什么不给微信特权?

::: block-1 “时问桫椤”是一个致力于为本科生到研究生教育阶段提供帮助的不太正式的公众号。我们旨在在大家感到困惑、痛苦或面临困难时伸出援手。通过总结广大研究生的经验&#xff0c;帮助大家尽早适应研究生生活&#xff0c;尽快了解科研的本质。祝一切顺利&#xff01;—…

# 从浅入深 学习 SpringCloud 微服务架构(七)Hystrix(4)

从浅入深 学习 SpringCloud 微服务架构&#xff08;七&#xff09;Hystrix&#xff08;4&#xff09; 一、hystrix&#xff1a;使用 turbine 聚合所有的 hytrix 的监控数据测试。创建父工程 spring_cloud_hystrix_demo&#xff0c;导入相关依赖坐标。并在父工程 spring_cloud_…

C语言/数据结构——每日一题(移除链表元素)

一.前言 今天在leetcode刷到了一道关于单链表的题。想着和大家分享一下。废话不多说&#xff0c;让我们开始今天的知识分享吧。 二.正文 1.1题目要求 1.2思路剖析 我们可以创建一个新的单链表&#xff0c;然后通过对原单链表的遍历&#xff0c;将数据不等于val的节点移到新…

图床搭建GitHub+PicGo+jsdelivr(CDN)+Typora(内附加速工具)

目录 安装PicGo GitHub配置与加速器 配置PicGo 使用typroa 安装PicGo PicGo是一个用于上传图片的客户端&#xff0c;支持拖拽上传、剪贴板上传&#xff0c;功能十分方便。 下载地址&#xff1a; https://github.com/Molunerfinn/PicGo/releases 个人网盘自取版本2.4.0…

了解并学会使用反射

目录 一、反射的应用场景&#xff08;简单了解&#xff09; 二、反射的定义 三、关于反射的四个重要的类 四、反射的使用 1.Class获取一个class对象的方式 方式一&#xff1a;forName&#xff08;&#xff09;&#xff1a; 方式二&#xff1a;封装类.Class&#xff1a; …

【stomp 实战】Spring websocket 用户订阅和会话的管理源码分析

通过Spring websocket 用户校验和业务会话绑定我们学会了如何将业务会话绑定到spring websocket会话上。通过这一节&#xff0c;我们来分析一下会话和订阅的实现 用户会话的数据结构 SessionInfo 用户会话 用户会话定义如下&#xff1a; private static final class Sessio…

怎么让电脑耳机和音响都有声音

电脑耳机音响不能同时用没声音怎么办 一般来说&#xff0c;重新开机后问题能够得到解决。右击“我的电脑”---“属性”---“硬件”---“设备管理器”&#xff0c;打开“声音、视频和游戏控制器”有无问题&#xff0c;即看前面有没有出现黄色的“”。 如果您的 电脑 耳机能正常…

VMware虚拟机中ubuntu使用记录(4)—— 如何在VMware虚拟机中调用本机电脑的摄像头

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、虚拟机调用本机摄像头(1) 启动VMware USB 服务(2) 连接本机摄像头(3) 测试摄像头的连接 前言 通过配置虚拟机调用本机摄像头&#xff0c;用户可以在虚拟机…

Redis---------实现商品秒杀业务,包括唯一ID,超卖问题,分布式锁

订单ID必须是唯一 唯一ID构成&#xff1a; 代码生成唯一ID&#xff1a; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.tim…

【论文阅读】Learning Texture Transformer Network for Image Super-Resolution

Learning Texture Transformer Network for Image Super-Resolution 论文地址Abstract1. 简介2.相关工作2.1单图像超分辨率2.2 Reference-based Image Super-Resolution 3. 方法3.1. Texture TransformerLearnable Texture Extractor 可学习的纹理提取器。Relevance Embedding.…

Qt QImageWriter类介绍

1.简介 QImageWriter 用于写入图像文件的类。它提供了将 QImage 对象保存到不同图像格式文件的功能&#xff0c;包括但不限于 PNG、JPEG、BMP 等。QImageWriter 可以将图像写入文件&#xff0c;也可以写入任何 QIODevice&#xff0c;如 QByteArray&#xff0c;这使得它非常灵活…

python中type,object,class 三者关系

type,object,class 三者关系 在python中&#xff0c;所有类的创建关系遵循&#xff1a; type -> int -> 1 type -> class -> obj例如&#xff1a; a 1 b "abc" print(type(1)) # <class int> 返回对象的类型 print(type(int)) …

基于OpenCv的图像金字塔

⚠申明&#xff1a; 未经许可&#xff0c;禁止以任何形式转载&#xff0c;若要引用&#xff0c;请标注链接地址。 全文共计3077字&#xff0c;阅读大概需要3分钟 &#x1f308;更多学习内容&#xff0c; 欢迎&#x1f44f;关注&#x1f440;【文末】我的个人微信公众号&#xf…

【讲解如何OpenCV入门】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

需求规格说明书编制书(word原件)

1 范围 1.1 系统概述 1.2 文档概述 1.3 术语及缩略语 2 引用文档 3 需求 3.1 要求的状态和方式 3.2 系统能力需求 3.3 系统外部接口需求 3.3.1 管理接口 3.3.2 业务接口 3.4 系统内部接口需求 3.5 系统内部数据需求 3.6 适应性需求 3.7 安全性需求 3.8 保密性需…

GiantPandaCV | FasterTransformer Decoding 源码分析(二)-Decoder框架介绍

本文来源公众号“GiantPandaCV”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;FasterTransformer Decoding 源码分析(二)-Decoder框架介绍 作者丨进击的Killua 来源丨https://zhuanlan.zhihu.com/p/669303360 编辑丨GiantPand…

【Python编程实践1/3】模块

目录 目标 模块 import ​编辑 代码小结 题目 from...import 随机模块 代码小结 randint函数 骰子大战 choice函数 总结 目标 拧一颗螺丝&#xff0c;只会用到螺丝刀&#xff1b;但是修一台汽车&#xff0c;需要一整套汽修的工具。函数就像螺丝刀&#xff0c;可以帮…

python项目==一个web项目,配置模板指定文件清洗规则,调用模板规则清洗文件

代码地址 一个小工具。 一个web项目&#xff0c;配置模板指定文件清洗规则&#xff0c;调用模板规则清洗文件 https://github.com/hebian1994/csv-transfer-all 技术栈&#xff1a; SQLite python flask vue3 elementplus 功能介绍&#xff1a; A WEB tool for cleaning…

JavaScript:Web APIs(三)

本篇文章的内容包括&#xff1a; 一&#xff0c;事件流 二&#xff0c;移除事件监听 三&#xff0c;其他事件 四&#xff0c;元素尺寸与位置 一&#xff0c;事件流 事件流是什么呢&#xff1f; 事件流是指事件执行过程中的流动路径。 我们发现&#xff0c;一个完整的事件执行…

Delta lake with Java--利用spark sql操作数据1

今天要解决的问题是如何使用spark sql 建表&#xff0c;插入数据以及查询数据 1、建立一个类叫 DeltaLakeWithSparkSql1&#xff0c;具体代码如下&#xff0c;例子参考Delta Lake Up & Running第3章内容 import org.apache.spark.sql.SaveMode; import org.apache.spark.…