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,一经查实,立即删除!

相关文章

linux下C热补丁

linux运行进程热补丁&#xff08;一&#xff09;之函数替换_linux 热补丁的实现-CSDN博客 一、实现目标 在Linux环境下&#xff08;x86_64&#xff09;对正在运行进程的函数替换&#xff0c;不改变该进程的可执行文件内容&#xff0c;通过使用汇编指令JMP完成运行中进程的函数…

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

::: 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_…

简历总结:打造HR无法拒绝的简历

最近要秋招实习了&#xff0c;看了一下实习简历应该如何正确展开书写&#xff0c;写下这篇博客来记录一下。 油管&#xff1a;神奇4步法&#xff0c;打造HR无法拒绝的简历 明确目标 针对不同的岗位编写不同的简历&#xff0c;具体内容可以针对不同岗位的要求。 筛选经历 将自…

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集群的创建安装与配置,以及维护

一、redis集群配置 port 7000 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes 二、安装ruby&#xff08;ruby可以充当redis客户端的角色&#xff09; yum -y install ruby ruby-devel rubygems rpm-build gem install …

【SQL】根据条件分组,并根据条件取最大的这一条数据

数据&#xff0c;当字段A相同时&#xff0c;取字段B数值大的这一条数据 ABC123114223234 期望结果 ABC123234 Oracle SELECT A, B, C FROM (SELECT A, B, C,ROW_NUMBER() OVER (PARTITION BY A ORDER BY B DESC) AS rnFROM 表名 ) WHERE rn 1; MySql SELECT t1.A, t1.B,…

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…

Java内存中的垃圾回收是如何实现的

Java内存中的垃圾回收是通过Java虚拟机&#xff08;JVM&#xff09;的垃圾收集器&#xff08;Garbage Collector&#xff09;来实现的。垃圾收集器自动管理Java堆内存中的对象&#xff0c;通过识别并回收不再使用的对象来释放内存空间&#xff0c;从而防止内存泄漏和内存溢出等…

JAVASE相关知识补充

基础知识 类作为成员变量类型&#xff1a; 接口作为成员变量类型&#xff1a; 接口作为方法的参数或者返回值 Object类&#xff1a; java.lang.object 类object是类层次结构的超&#xff08;根&#xff09;类 每个类都是用object作为父类 所有对象包括数组都实现这个类的…

【论文阅读】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.…

什么是binutils-arm-linux-gnueabi

2024年5月3日&#xff0c;周五晚上 binutils-arm-linux-gnueabi 是针对 ARM 架构的 Linux 系统开发的 GNU Binutils 工具链。Binutils 是一组用于汇编、链接和转换目标文件的工具&#xff0c;包括 as (汇编器)、ld (链接器)、objcopy (目标文件转换工具) 等。 binutils-arm-li…

【Nginx 开发】Nginx高可用集群

配置集群 高可用集群配置高可用集群 高可用集群 为什么需要配置Nginx集群&#xff1a; 在实际开发过程中Nginx也有可能宕机&#xff0c;如果我们能够将Nginx配置成高可用&#xff0c;当Nginx宕机之后&#xff0c;在集群中我们可以将请求转发到从Nginx服务器当中&#xff0c;由…

【代码随想录——数组篇】

代码随想录——数组篇 2. 二分查找3. 移除元素4. 有序数组的平方5. 长度最小的子数组6. 螺旋矩阵II 2. 二分查找 力扣题目链接 前提&#xff1a; 有序数组数组中无重复元素 代码&#xff1a; &#xff08;版本一&#xff09;左闭右闭区间 class Solution {public int sea…

AcWing 850. Dijkstra求最短路 II

Problem: AcWing 850. Dijkstra求最短路 II 文章目录 思路解题方法复杂度Code 思路 这是一个经典的 Dijkstra 算法问题&#xff0c;我们需要找到从点 1 到点 n 的最短路径。Dijkstra 算法是一种贪心算法&#xff0c;它总是选择当前未访问过的节点中距离最短的一个&#xff0c;然…