SpringBoot学习(四) 缓存、消息队列、消息队列、检索、任务

一.springboot与缓存

spring 缓存抽象

1.几个重要概念&缓存注解

概念/注解解释说明
Cache缓存接口,定义缓存操作。实现有RedisCache,EhCache,ConcurrentMapCache等
CacheManager缓存管理器,管理各种缓存组件
@Cacheable主要针对方法配置,能根据方法的请求参数对其结果进行缓存
@CacheEvict清空缓存
@CachePut保证方法被调用,又希望结果被缓存
@EnableCaching开启基于注解的缓存
keyGenerator缓存数据的时候,key的生成策略
serialize缓存数据时,value的生成策略

2.快速体验缓存

步骤:
1.开启基于注解的缓存 @EnableCaching

@MapperScan("com.pt.cache.mapper")
@SpringBootApplication
@EnableCaching
public class CacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(CacheApplication.class, args);
    }

}

2.在方法上标注缓存注解 @Cacheable即可

@Service
public class UserService {
    @Autowired
    UserMapper userMapper;

    @Cacheable
    public User getUserById(Integer id){

        User user= userMapper.getUserById(id);
        return user;
    }
}

3.说明

将方法的运行结果进行缓存,以后再要相同的数据,直接从缓存中获取,不调用方法。
CacheManager管理多个Cache.对缓存的正常curd操作在cache组件中,每一个缓存组件有自己唯一的名字。

4. @Cacheable

几个属性:

cacheNames/value : 指定缓存的名字
key:缓存数据使用的key。可以用它来指定,默认是使用方法参数的值
keyGenerator:key的生成器,可以自己指定生成器。(和key二选一)
cacheManager :指定缓存管理器
condition:指定符合条件的情况下才缓存
unless 是否缓存;当unless指定的条件为true,方法的返回值就不会被缓存

运行流程

@Cacheable:
1.方法运行之前,先去查询Cache (缓存组件),按照cacheNames指定的名字获取;(CacheManager先获取相应的缓存),第一次获取缓存如果没有Cache组件会自动创建

2.去Cache中查找缓存内容,使用一个key(默认就是方法的参数);
key是按照某种策略生成的;默认是使用keyGenerator生成的,默认使用SimplekeyGenerator生成。

SimplekeyGenerator生成策略:
如果方法没有参数,key=new SimpleKey() 如果有一个参数,key=参数值
如果有多个参数,key=new SimpleKey(parms …)

3.没有查到缓存就是调用方法

4.将目标方法的返回值放入缓存中

5.原理

1.自动配置类 CacheAutoConfiguration
2.缓存的配置类,会有一堆缓存配置类
3.哪个配置类默认生效?SimpleCacheConfiguration
4.给容器中注册了一个CacheManager
5.可以获取和创建一个ConcurrentMapCacheManager类型的缓存组件,他的作用是将数据保存到ConcurrentMap中

核心:

1.CacheManager [ ConcurrentMapCacheManager] 按照名字得到Cache【ConcurrentMapCache】组件
2.key是使用keyGenerator生成的。默认是SimplekeyGenerator

6.@CachePut 缓存更新

@CachePut 即调用方法,又更新数据库
修改数据库的某个数据,同时更新缓存
运行时机:
1.先调用目标方法
2.将目标方法的结果缓存起来

7.@CacheEvict 缓存清除

一般使用在删除的时候,用来清空缓存的
属性:
key 可以指定删除的缓存的id
allEntries = true 是否删除全部缓存,默认false
beforeInvocation = false 缓存的清除是否在方法之前执行。默认方法执行之后执行,如果方法出错了的话,就不会清空缓存了。

8.@Caching 定义复杂缓存规则

@Cacheable,@CachePut @CacheEvict 的混合注解。

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Caching {
    Cacheable[] cacheable() default {};

    CachePut[] put() default {};

    CacheEvict[] evict() default {};
}

使用

    @Caching(
            cacheable = {@Cacheable(value = "user",key = "#userName")},
            put = {@CachePut(value = "user",key = "#result.id"),
                    @CachePut(value = "user",key = "#result.passWord")
            }
    )
    public User getUserById(Integer id){

        User user= userMapper.getUserById(id);
        return user;
    }

9.CacheConfig

写在类上,可以指定公共的cache属性

@CacheConfig(cacheNames = "user")
@Service
public class UserService {

公共配置过的,后面的Cache可以不用配置了

10.redis 缓存

1.安装redis,可以作为数据库,缓存,消息中间件
docker中

docker pull redis

2.引入redis的starter

     <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

3.配置redis

spring.redis.host=主机地址
   @Autowired
    StringRedisTemplate stringRedisTemplate; //操作k-v都是字符串
    @Autowired
    RedisTemplate redisTemplate; //k-v都是对象
    @Autowired
    RedisTemplate<Object,User> userRedisTemplate; //自定义RedisTemplate
    /**
     *Redis常见的五大数据类型
     * String(字符串),List(列表),Set(集合),Hash(散列),ZSet(有序集合)
     * StringRedisTemplate.opsForValue() 作用于String(字符串)
     * stringRedisTemplate.opsForList() 作用于List
     * ...
     */

    public void test(){
       stringRedisTemplate.opsForValue().append("msg","hello");
        String msg = stringRedisTemplate.opsForValue().get("msg");
    }
    
    public void test2(){
        User user = new User(1, "uname", "pwd");
        //保存对象的话,默认使用jdk序列化机制,序列化后保存到redis中
       // redisTemplate.opsForValue().set("user",user);
        //如果不想用默认的,可以以转换为json格式保存
        //方法1:自己转换为json
        //方法2:自定义redisTemplate默认的序列化规则
        userRedisTemplate.opsForValue().set("user01",user);
    }

//方法2:自定义redisTemplate默认的序列化规则

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<Object, User> redisTemplate(RedisConnectionFactory redisConnectionFactory) {

        RedisTemplate<Object,User>  template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        Jackson2JsonRedisSerializer<User> userJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<User>(User.class);
        template.setDefaultSerializer(userJackson2JsonRedisSerializer);
        return template;
    }
}

二.springboot与消息队列

一些概念

1.消息服务中有两个重要概念:

消息代理(message broker)== 和 目的地(destination)
当消息发送者发送消息的时候,将由消息代理接管,消息代理保证消息传递到指定目的地。

2.消息队列主要有两种形式的目的地

1.队列(queue) :点对点消息通信(point-to-point)
2.主题(topic):发布(publish)/订阅(subscribe)消息通信

3.点对点式:

消息发送者发送消息到队列中,消息接收者从队列中获取消息,获取后消息从队列中移除。
消息有唯一的发送者,有多个接受者,有唯一的接收者。就是说,可以多个接受者来拿消息,但只有一个能拿到。

4.发布订阅式:

发送者(发布者)发送消息到主题,可以有多个接收者(订阅者)监听(订阅)这个主题,那么就会在消息到达的时候,同时接收到消息。

5.JMS(java message service) java消息服务

基于JVM的消息代理规范。如,ActiveMQ,HornetMQ就是JMS实现

6.AMQP(advianced message queuing protocol)

高级消息队列,也是一个消息代理的规范,兼容JMS
如,RabbitMQ就是AMQP实现

JMSAMQP比较
java api网络线级协议定义
否,java跨语言
夸平台
提供两种:1 .peer-2-peer 点对点 2.pub/sub 发布/订阅提供五种,第一种也是点对点,后面四种和 pub/sub没什么区别,但是在路由机制上做了更详细的规划Model
TextMessage,MapMessage, BytesMessage, StreamMessasge, ObjectMessage, Message(只有消息头和属性)byte[]支持消息类型

7.Spring的支持

1.spring-jms 提供对JMS的支持
2.spring-rabbit 提供对AMQP的支持
3.需要ConnectionFactory的实现来连接消息代理
4.提供JmsTemplate,RabbitTemplate来发送消息
5.@JmsListener 和 @RabbitListener 注解在方法上监听消息代理发布消息
6.@EnableJms,@EnableRabbit 开启支持

8.SpringBoot自动配置

JmsAutoConfiguration
RabbitAutoConfiguration

RabbitMQ

核心概念

1.Message 消息
2.Publisher 消息的生产者,
3.Exchange 交换器
4.Queue 消息队列
5.Binding 绑定
6.Connection 网络连接
7.Channel 信道
8.Consumer 消息的消费者
9.Virtual Host 虚拟主机,表示一批交换机,消息队列和相关对象。
10.Broker 表示消息队列服务器实体

rabbit与springboot整合与使用

pom.xml引入rabbitmq

       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

application配置文件中配置rabbitmq基本属性

spring.rabbitmq.host=主机地址
#默认用户密码guest
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

来到UserService

@Service
public class UserService {
   @Autowired
    RabbitTemplate rabbitTemplate;
    //单播
    public void test3(){
      //需要定义一个Message
     //rabbitTemplate.send(exchange,routeKey,message);
     //值需要传递要发送的对象,自动序列化,默认java方式序列化,可以自定义配置类修改
     //rabbitTemplate.convertAndSend(exchange,routeKey,Object);

        //交换器名字
        String exchange="exchange.direct";
        //路由键的名字
        String routeKey="pt.news";
        Map<String,Object> map = new HashMap<>();
        map.put("msg","第一个");
        map.put("data","第二个");
        rabbitTemplate.convertAndSend(exchange,routeKey,map);

        //接收消息
        Object o = rabbitTemplate.receiveAndConvert("pt.mews");
    }

    //广播
    public void test4(){
        //不需要指定key了
        rabbitTemplate.convertAndSend("exchange.fanout","","object");
    }

}

实用消息监听
监听Queue或Binding,当有消息的时候,就会调用这个方法

    @RabbitListener(queues = "pt.news")
    public void test5(User user){
        System.out.println("pt.news收到消息,就会调用这个方法"+user);
    }

要使用@RabbitListener注解,还需要开启注解支持

@EnableRabbit
public class CacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(CacheApplication.class, args);
    }

}

@AmqpAdmin : RabbitMQ系统管理功能组件
创建和删除Queue,Exchange,Binding


    @Autowired
    AmqpAdmin amqpAdmin;

    public void test6(){
        amqpAdmin.declareExchange(new DirectExchange("abc.exchange"));
        System.out.println("创建exahnge完成");

       //创建Binding规则

        amqpAdmin.declareBinding(new Binding("abc.queue",Binding.DestinationType.QUEUE,"abc.exchange","abc.key",null));
        
        //删除
        amqpAdmin.deleteExchange("abc.exchange");
    }

三.springboot与检索

ElasticSearch

ElasticSearch是分布式搜索服务,提供Restful API,底层基于lucen.

springboot整合ElasticSearch

导入pom依赖

  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>

写Repository继承ElasticsearchRepository

public interface UserRepository extends ElasticsearchRepository<User,Integer> {
    List<User> findByUserNameLike(String UserName);
}

配置文件中指定基本信息

spring.elasticsearch.rest.uris=127.0.0.1:9300
spring.elasticsearch.rest.username=elasticsearch

实体类得加上@Document

@Document(indexName = "pt")
public class User {

service中就可以使用了

   @Autowired
    UserRepository userRepository;

    public void test7(){
       User user=new User(1,"123","abc");
       for (User u : userRepository.findByUserNameLike("1")){
           System.out.println(u);
       }

    }

docker 安装ElasticSearch

安装的时候看一下Springboot对应的版本
在这里插入图片描述

docker pull elasticsearch:7.9.3

docker images后查看到容器id

docker images

docker 启动 运行 ElasticSearch
因为默认启动得2G,所以需要设置一下内存
并且加上-e “discovery.type=single-node”

docker run -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -e “discovery.type=single-node” -d -p 9201:9200 -p 9301:9300 --name ES02 a7e1d4b5ee81

四.springboot与任务

1.异步任务

启动类上添加@EnableAsync,开启异步

@EnableAsync
public class CacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(CacheApplication.class, args);
    }

}

方法上添加@Async,表示这个是一个异步方法,不会影响主线程

    @Async
    public void test08(){
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("处理数据...");
    }

2.定时任务

基本使用

启动类添加@EnableScheduling上开启定时任务的注解

@EnableScheduling
public class CacheApplication {

方法上添加 @Scheduled 表示定时任务,按照cron上的规则执行

    //cron: 秒,分,时,day of month,month,day of week
    //如:   0 * * * * MON-FRI   周一到周五每一分钟运行一次
    //*表示任意时刻
    @Scheduled(cron = "0 * * * * MON-FRI")
    public void test09(){
        System.out.println("定时任务运行了一次");
    }

cron表达式:

字段允许值允许的特殊符号
0-59,-*/
0-59,-*/
小时0-23,-*/
日期1-31,-*/?LWC
月份1-12,-*/
星期0-7或者SUN-SAT 0,7是SUN,-*/?LC#

特殊符号:

符号意义
枚举
-区间
*任意
/步长
日/星期冲突匹配
L最后
W工作日
C和calendar联系后计算过的值
#星期,4#2,第二个星期四

3.邮件任务

导入pom.xml的依赖

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>

配置一些基本信息

spring.mail.username=1111111@qq.com
spring.mail.password=授权码
spring.mail.host=smtp.qq.com
#安全连接
spring.mail.properties.mail.smtp.ssl.enable=true

授权码的获取,到qq邮箱中获取
在这里插入图片描述
简单的邮件发送


    @Autowired
    JavaMailSenderImpl javaMailSender;
    
  public void test010(){
        SimpleMailMessage mailMessage=new SimpleMailMessage();
        //邮件设置
        mailMessage.setSubject("通知-今晚开会");
        mailMessage.setText("晚上7.30开会");
        mailMessage.setTo("sqdpt666@163.com");
        mailMessage.setFrom("2624890652@qq.com");
        javaMailSender.send(mailMessage);

    }

带附件的邮件发送

    //带附件的邮件发送
    public void test011() throws MessagingException {
        MimeMessage mimeMessage=javaMailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
        helper.setSubject("通知-今晚开会");
        //后面为true表示发送的是html,默认为false
        helper.setText("<h1>730kaihui</h1>",true);
        helper.setTo("sqdpt666@163.com");
        helper.setFrom("2624890652@qq.com");
        helper.addAttachment("1.jpg",new File("D:\\1.jpg"));
        javaMailSender.send(mimeMessage);


    }
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 1024 设计师:上身试试 返回首页