Spring Boot第八章-非关系型数据库(MongoDB,Redis)

Spring Boot第八章-非关系型数据库(MongoDB,Redis)

                                                                 Spring Boot第八章-非关系型数据

目录

1.MongoDB

1.1 介绍

1.2 Spring的支持

1.2.1 Object/Document 映射注解支持

1.2.2 MongoTemplate

1.2.3 Repository的支持

1.3 Spring Boot的支持

1.4 Spring Boot Mongo实战

1.4.1 MongoDB安装

1.4.2 搭建Spring Boot项目

1.4.3 主要代码

1.4.4 测试结果

2 redis

2.1 Spring的支持

2.1.1 配置

 2.1.2 使用

2.1.3 定义Serializer

2.2 Spring Boot的支持

2.3 Spring Boot Redis实战

2.3.1 安装Redis

2.3.2 增加依赖

2.3.3 主要代码

2.3.4 测试结果

项目地址

3.redis的发布订阅

3.1 redis发布订阅原理

3.2 测试例子

3.3 测试结果


1.MongoDB

1.1 介绍

  MongoDB是一个是一个基于文档(Document)的存储型数据库,使用面向对象的思想,每一条数据文档的对象。来自菜鸟教程的解释是:

MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。

MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。

1.2 Spring的支持

1.2.1 Object/Document 映射注解支持

  JPA提供了一套Object/Relation映射的注解(如@Entity,@Id),而Spring Data MongoDB也提供了一套注解:

@Document:映射领域对象与MongoDB的一个文档,类似于hibernate的@Entity注解

@Id:主键,不可重复,自带索引

@Field:为文档的属性定义名称

@Indexed: 为该字段加索引

@CompoundIndex:符合索引

@DBRef:关联另一个document对象,但不会级联表

1.2.2 MongoTemplate

 类似于jdbcTemplate

1.2.3 Repository的支持

和Spring Data JPA的使用方式一样,需要在配置类上加上@EnableMongoRepositories注解

1.3 Spring Boot的支持

 Spring Boot对MongoDB的支持,位于:org.springframework.boot.autoconfigure.mongo

在配置文件中,以”spring.data.mongodb”为前缀的属性配置MongoDB的信息

Spring Boot提供了一些默认属性以及自动配置,默认端口27017,host为localhost,数据库为test

1.4 Spring Boot Mongo实战

1.4.1 MongoDB安装

虚拟机内docker安装MongoDB,直接安装官方的

  • docker search mongo      查看官方mongo
  • docker pull mongo           拉取mongo镜像
  • docker images mongo     查看mongo镜像
  • docker run -p 27017:27017 -v $PWD/db:/data/db -d mongo:3.2

可视化工具Robo 3T,增加用户,查看,管理Mongo数据内容非常方便,已上传到百度网盘,

链接: https://pan.baidu.com/s/1oRRftXKtgdAJewFF3v0sAg 密码: yy84

1.4.2 搭建Spring Boot项目

新建Spring Boot项目,依赖spring-boot-starter-data-mongodb和spring-boot-starter-web

我的配置信息,虚拟机上安装的Mongo,ip是虚拟机的ip:

#mongodb的配置,springboot已经给我们做了很多默认配置,配置自己需要修改的地方就行了
#默认localhost
spring.data.mongodb.host=192.168.4.219  
spring.data.mongodb.port=27017

#connection url 默认数据库为test
#spring.data.mongodb.uri=mongodb://192.168.4.219/test
#spring.data.mongodb.database=test
#spring.data.mongodb.authentication-database=test
#spring.data.mongodb.username=admin
#spring.data.mongodb.password=123456
##默认开启
#spring.data.mongodb.repositories.enabled=true

1.4.3 主要代码

领域模型:

package com.just.springbootnosql.domain;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

import java.util.Collection;

@Document  //映射领域模型和mongoDB的文档
public class Person {
    @Id
    private String id;
    private String name;
    private Integer age;
    @Field("locs") //此属性在文档中的名字是locs,locations属性将以数组形式存在当前数据记录中
    private Collection<Location> locations;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Collection<Location> getLocations() {
        return locations;
    }

    public void setLocations(Collection<Location> locations) {
        this.locations = locations;
    }
}

Location

package com.just.springbootnosql.domain;

public class Location {
    private String place;
    private String year;

    public Location(String place, String year) {
        this.place = place;
        this.year = year;
    }

    public String getPlace() {
        return place;
    }

    public void setPlace(String place) {
        this.place = place;
    }

    public String getYear() {
        return year;
    }

    public void setYear(String year) {
        this.year = year;
    }
}

数据访问:

package com.just.springbootnosql.dao;

import com.just.springbootnosql.domain.Person;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;

import java.util.List;

public interface PersonRepository extends MongoRepository<Person,String> {
    //支持方法名查询
    Person findByName(String name);

    //支持@Query查询,查询参数构造JSON字符串即可
    @Query("{'age':?0}")
    List<Person> withQueryByAge(Integer age);
}

控制器:

package com.just.springbootnosql.controller;

import com.just.springbootnosql.dao.PersonRepository;
import com.just.springbootnosql.domain.Location;
import com.just.springbootnosql.domain.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;

@RestController
@RequestMapping("/person")
public class PersonController {
    @Autowired
    private PersonRepository personRepository;
    @PostMapping("/save")
    public Person save(@RequestBody Person person){
        Collection<Location> locations=new LinkedHashSet<>();
        Location location1=new Location("南京","2016");
        Location location2=new Location("常州","2016");
        Location location3=new Location("上海","2017");
        Location location4=new Location("上海","2018");
        locations.add(location1);
        locations.add(location2);
        locations.add(location3);
        locations.add(location4);
        person.setLocations(locations);
        return personRepository.save(person);
    }
    @GetMapping("/findByName")
    public Person findByName(String name){
        return personRepository.findByName(name);
    }
    @GetMapping("/findByAge")
    public List<Person> findByAge(Integer age){
        return personRepository.withQueryByAge(age);
    }
}

1.4.4 测试结果

controller测试结果:

Spring Boot第八章-非关系型数据库(MongoDB,Redis)

Spring Boot第八章-非关系型数据库(MongoDB,Redis) Spring Boot第八章-非关系型数据库(MongoDB,Redis)

mongodb数据:

Spring Boot第八章-非关系型数据库(MongoDB,Redis)

2 redis

Redis是一个基于键值对的开源内存数据存储

2.1 Spring的支持

2.1.1 配置

Spring对Redis的支持也是通过Spring Data Redis来实现的。

根据Redis的不同的Java客户端,Spring Data Redis提供了以下的ConnectionFactory,可以在

org.springframework.data.redis.connection 这个目录下找到各种ConnectionFactory:

JedisConnectionFactory,JredisConnectionFactory,LettuceConnectionFactory等等

Spring Boot第八章-非关系型数据库(MongoDB,Redis)

 2.1.2 使用

Spring Data Redis提供了RedisTemplate和StringRedisTemplate两个模板进行数据操作,其中StringRedisTemplate只针对键值都是字符串的数据类型进行操作

常用的数据访问方法:

opsForValue(): 简单属性

opsForList(): 操作含有list的数据

opsForSet(): 操作含有set的数据

opsForZSet(): 操作含有ZSet(有序的set)的数据

opsForHash(): 操作含有hash的数据

具体的操作将在持续更新的代码中体现

2.1.3 定义Serializer

定义键值序列化方式,Spring Data JPA提供了好几种序列化方式,RedisTemplate默认使用的是JdkSerializationSerializer。其他常用的具体详见代码

2.2 Spring Boot的支持

Spring Boot对Redis做了自动配置,org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration。

Spring Boot配置文件”spring.redis”为前缀的可以配置redis相关参数

2.3 Spring Boot Redis实战

2.3.1 安装Redis

docker安装redis,类似于mongoDB的安装,直接关键步骤就行了

  • docker pull redis
  • docker run redis –name redis -p 6379:6379 -d redis-server

windows上redis的安装教程很多,自行查找吧

redis的可视化工具:redis desktop manager,已放到百度网盘:

链接: https://pan.baidu.com/s/1SkIXmn1IkGrz-lUokzhyhA 密码: brui

2.3.2 增加依赖

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

配置信息:

# Redis服务器地址
spring.redis.host=192.168.4.219
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=

2.3.3 主要代码

新建一个user类:

package com.just.springbootnosql.domain;

import java.io.Serializable;

public class User implements Serializable {
    private static final long serialVersionUID=1L;
    private String id;
    private String name;
    private Integer age;

    public User(){
        super();
    }
    public User(String id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
    /**省略setter和getter**/
}

service层,用redisTemplate操作

redis有五种数据类型,redisTemplate对其的操作做了封装,可以在实际中看看他们的用法,这里只是测试常用的方法,每一种都有好多方法,可以自己去测试。

/**
 * 结构类型    结构存储的值    结构的读写能力
 * String    可以是字符串、整数或者浮点数    对整个字符串或者字符串的其中一部分执行操作;对象和浮点数执行自增(increment)或者自减(decrement)
 * List    一个链表,链表上的每个节点都包含了一个字符串    从链表的两端推入或者弹出元素;根据偏移量对链表进行修剪(trim);读取单个或者多个元素;根据值来查找或者移除元素
 * Set    包含字符串的无序收集器(unorderedcollection),并且被包含的每个字符串都是独一无二的、各不相同    添加、获取、移除单个元素;检查一个元素是否存在于某个集合中;计算交集、并集、差集;从集合里卖弄随机获取元素
 * Hash    包含键值对的无序散列表    添加、获取、移除单个键值对;获取所有键值对
 * Zset    字符串成员(member)与浮点数分值(score)之间的有序映射,元素的排列顺序由分值的大小决定    添加、获取、删除单个元素;根据分值范围(range)或者成员来获取元素
 */

package com.just.springbootnosql.service;

import com.just.springbootnosql.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 结构类型	结构存储的值	结构的读写能力
 * String	可以是字符串、整数或者浮点数	对整个字符串或者字符串的其中一部分执行操作;对象和浮点数执行自增(increment)或者自减(decrement)
 * List	一个链表,链表上的每个节点都包含了一个字符串	从链表的两端推入或者弹出元素;根据偏移量对链表进行修剪(trim);读取单个或者多个元素;根据值来查找或者移除元素
 * Set	包含字符串的无序收集器(unorderedcollection),并且被包含的每个字符串都是独一无二的、各不相同	添加、获取、移除单个元素;检查一个元素是否存在于某个集合中;计算交集、并集、差集;从集合里卖弄随机获取元素
 * Hash	包含键值对的无序散列表	添加、获取、移除单个键值对;获取所有键值对
 * Zset	字符串成员(member)与浮点数分值(score)之间的有序映射,元素的排列顺序由分值的大小决定	添加、获取、删除单个元素;根据分值范围(range)或者成员来获取元素
 */
@Service
@SuppressWarnings("unchecked")
public class UserServiceImpl implements UserService{
//    @Autowired
//    private JedisCluster jedisCluster;
    @Autowired
    private RedisTemplate redisTemplate;


    @Override
    public String findRedis() {
        redisTemplate.opsForValue().set("userName","呵呵哒");
        return redisTemplate.opsForValue().get("userName").toString();
    }

    @Override
    public List<User> cacheUsers() {
        List<User> users=new ArrayList<>();
        User user1=new User("1","阿西吧",12);
        User user2=new User("2","阿西九",20);
        User user3=new User("3","阿西十",18);
        users.add(user1);
        users.add(user2);
        users.add(user3);
        redisTemplate.opsForList().leftPush("user.list",user1);
        redisTemplate.opsForList().leftPush("user.list",user2);
        redisTemplate.opsForList().leftPush("user.list",user3);
        //第二种方式
        //redisTemplate.delete("users.list");
        //redisTemplate.opsForList().leftPushAll("user.list",users);
        redisTemplate.expire("user.list",30,TimeUnit.SECONDS);
        return redisTemplate.opsForList().range("user.list",0L,-1L);
    }

    @Override
    public Map<String, User> cacheUserMap() {
        User user=new User("4","测试hash",66);
        User user1=new User("6","测试hash",67);
        User user2=new User("7","测试hash",68);
        User user3=new User("8","测试hash",69);
        Map<String,User> map=new HashMap<>();
        map.put(user1.getId(),user1);
        map.put(user2.getId(),user2);
        map.put(user3.getId(),user3);
        //第一种方式,单个加入
        redisTemplate.opsForHash().put("user.map","4",user);
        //第二种方式,整个map加入
        redisTemplate.opsForHash().putAll("user.map",map);
        return redisTemplate.opsForHash().entries("user.map");
    }

    @Override
    public User findUser(String id) {
        return (User) redisTemplate.opsForHash().get("user.map",id);
    }

    @Override
    public Set<User> cacheUserSet() {
        Set<User> userSet=new HashSet<>();
        User user1=new User("10","测试set",20);
        User user2=new User("11","测试set",21);
        User user3=new User("12","测试set",22);
        userSet.add(user1);
        userSet.add(user2);
        userSet.add(user3);
        //只能一个一个放进去。。。
        redisTemplate.opsForSet().add("user.set",user1,user2,user3);
        return redisTemplate.opsForSet().members("user.set");
    }

    /**
     * zSet:字符串成员(member)与浮点数分值(score)之间的有序映射,元素的排列顺序由分值的大小决定
     */
    @Override
    public Set<User> cacheUserZSet() {
        User user=new User("20","测试zset",13);
        User user1=new User("21","测试zset",14);
        User user2=new User("22","测试zset",15);
        User user3=new User("23","测试zset",16);

        redisTemplate.opsForZSet().add("user.zset",user,1.0);
        ZSetOperations.TypedTuple<Object> typedTuple1=new DefaultTypedTuple<>(user1,Double.valueOf(user1.getId()));
        ZSetOperations.TypedTuple<Object> typedTuple2=new DefaultTypedTuple<>(user2,Double.valueOf(user2.getId()));
        ZSetOperations.TypedTuple<Object> typedTuple3=new DefaultTypedTuple<>(user3,Double.valueOf(user3.getId()));
        Set<ZSetOperations.TypedTuple<Object>> tuples=new HashSet<>();
        tuples.add(typedTuple1);
        tuples.add(typedTuple2);
        tuples.add(typedTuple3);
        redisTemplate.opsForZSet().add("user.zset",tuples);
        return redisTemplate.opsForZSet().range("user.zset",0,-1);
    }
}

controller层,来测试redis各种数据结构效果

package com.just.springbootnosql.controller;

import com.just.springbootnosql.dao.UserDao;
import com.just.springbootnosql.domain.User;
import com.just.springbootnosql.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;
import java.util.Set;

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    UserDao userDao;
    @Autowired
    UserService userService;
    @RequestMapping("/save")
    public User saveUser(){
        User user=new User("1","哈哈哈",11);
        userDao.save(user);
        userDao.stringRedisTemplateDemo();
        return user;
    }
    @GetMapping("/getString")
    public String getString(){
       return userDao.getString();
    }

    @GetMapping("/getUser")
    public User getUser(){
        return userDao.getUser("1");
    }
    @GetMapping("/findRedis")
    public String findRedis(){
        return userService.findRedis();
    }
    @GetMapping("/testList")
    public List<User> findList(){
        return userService.cacheUsers();
    }
    @GetMapping("/map")
    public Map<String,User> findMap(){
        return userService.cacheUserMap();
    }
    @GetMapping("/getFromMap")
    public User findOneFromMap(String id){
        return userService.findUser(id);
    }
    @GetMapping("/set")
    public Set<User> findFromSet(){
        return userService.cacheUserSet();
    }
    @GetMapping("/zset")
    public Set<User> findFromZSet(){
        return userService.cacheUserZSet();
    }
}

2.3.4 测试结果

展示不同数据类型接口的测试结果

Spring Boot第八章-非关系型数据库(MongoDB,Redis)

Spring Boot第八章-非关系型数据库(MongoDB,Redis) Spring Boot第八章-非关系型数据库(MongoDB,Redis)

Spring Boot第八章-非关系型数据库(MongoDB,Redis) Spring Boot第八章-非关系型数据库(MongoDB,Redis)

Spring Boot第八章-非关系型数据库(MongoDB,Redis) Spring Boot第八章-非关系型数据库(MongoDB,Redis)

项目地址

https://gitee.com/yuanhan93/springbootnosql

补充内容:

3.redis的发布订阅

3.1 redis发布订阅原理

参考:https://blog.csdn.net/clh604/article/details/19754939

3.2 测试例子

新建一个接收类:

package com.just.springbootnosql;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.just.springbootnosql.domain.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;
public class Receiver {
    private static final Logger logger=LoggerFactory.getLogger(Receiver.class);
    private CountDownLatch latch;
    //我们给Receiver的构造函数通过@AutoWired标注注入了一个CountDownLatch实例,当接收到消息时,调用cutDown()方法。
    @Autowired
    public Receiver(CountDownLatch latch){
        this.latch=latch;
    }

    public void receiveMessage(String message){
        logger.info("receive message:"+message);
        latch.countDown();
    }

    public void receiveJsonMessage(String message){
        logger.info("receive json message:"+message);
        ObjectMapper mapper=new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        //GenericJackson2JsonRedisSerializer 里会有class的类路径,可以直接反序列化
        //GenericJackson2JsonRedisSerializer g=new GenericJackson2JsonRedisSerializer();
        try {
            User user=mapper.readValue(message,User.class);
            //User user=(User) g.deserialize(message.getBytes());
            logger.info("反序列化为user成功,userId:"+user.getId());
        } catch (Exception e) {
            logger.info("这不是user");
        }
        latch.countDown();
    }

}

在这个接受类中加入了CountDownLatch,为了在下面的测试代码中运行,能看到接收的效果,因为发送消息是异步的,在test代码中如果不用这个就看不到打印的效果。CountDownLatch能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。使用一个计数器进行实现。

CountDownLatch不是必要加的,只是为了测试方便!

在这个类里面有两个接收方法,一个是普通的string类型,另一个是json字符串,可以反序列化为对象

redis监听器配置:

package com.just.springbootnosql;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;

import java.util.concurrent.CountDownLatch;

@Configuration
public class RedisListenerConfig {
    /**
     * redis监听容器
     */
    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
                                            MessageListenerAdapter listenerAdapter,
                                            MessageListenerAdapter listenerJsonAdapter) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.addMessageListener(listenerAdapter, new PatternTopic("p_topic"));
        container.addMessageListener(listenerJsonAdapter, new PatternTopic("p_topic_json"));
        return container;
    }

    @Bean
    MessageListenerAdapter listenerAdapter(Receiver receiver) {
        return new MessageListenerAdapter(receiver, "receiveMessage");
    }

    /**
     * 在redisTemplate的配置中已经是json的序列化方式,这里不需要再进行序列化了
     */
    @Bean
    MessageListenerAdapter listenerJsonAdapter(Receiver receiver) {
        MessageListenerAdapter messageListenerAdapter=new MessageListenerAdapter(receiver, "receiveJsonMessage");
        return messageListenerAdapter;
    }

    @Bean
    Receiver receiver(CountDownLatch latch) {
        return new Receiver(latch);
    }

    @Bean
    CountDownLatch latch() {
        return new CountDownLatch(1);
    }


}

配置两个频道,并且配置两个频道的监听方法。由于redis的配置中已经对消息进行了序列化方式的处理,这里就不用再次序列化了。

测试:

package com.just.springbootnosql;

import com.just.springbootnosql.domain.User;
import org.json.JSONException;
import org.json.JSONObject;
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 SpringbootnosqlApplicationTests {
    @Autowired
    private RedisTemplate redisTemplate;
    @Test
    public void testRedisPub() throws JSONException {
        JSONObject jsonObject=new JSONObject();
        jsonObject.put("name","小李子");
        jsonObject.put("age",18);
        User user=new User();
        user.setId("1");
        user.setName("超级用户");
        user.setAge(0);
        redisTemplate.convertAndSend("p_topic","我来啦,呵呵哒");
        redisTemplate.convertAndSend("p_topic_json",jsonObject);
        redisTemplate.convertAndSend("p_topic_json",user);
    }

}

3.3 测试结果

不启动项目,直接test,testRedisPub()方法测试结果:

2018-09-05 10:55:03.557  INFO 15196 --- [    container-2] com.just.springbootnosql.Receiver        : receive message:"我来啦,呵呵哒"
2018-09-05 10:55:03.634  INFO 15196 --- [    container-3] com.just.springbootnosql.Receiver        : receive json message:["org.json.JSONObject",{"nameValuePairs":["java.util.HashMap",{"name":"小李子","age":18}]}]
2018-09-05 10:55:03.664  INFO 15196 --- [    container-4] com.just.springbootnosql.Receiver        : receive json message:["com.just.springbootnosql.domain.User",{"id":"1","name":"超级用户","age":0}]
2018-09-05 10:55:03.700  INFO 15196 --- [    container-3] com.just.springbootnosql.Receiver        : 这不是user
2018-09-05 10:55:03.703  INFO 15196 --- [    container-4] com.just.springbootnosql.Receiver        : 反序列化为user成功,userId:1
2018-09-05 10:55:03.714  INFO 15196 --- [       Thread-2] o.s.w.c.s.GenericWebApplicationContext   : Closing org.springframework.web.context.support.GenericWebApplicationContext@4758820d: startup date [Wed Sep 05 10:54:58 CST 2018]; root of context hierarchy
2018-09-05 10:55:03.716  INFO 15196 --- [       Thread-2] o.s.c.support.DefaultLifecycleProcessor  : Stopping beans in phase 2147483647
Disconnected from the target VM, address: '127.0.0.1:50580', transport: 'socket'

Process finished with exit code 0

启动项目,用redis客户端写语句发布消息测试:

Spring Boot第八章-非关系型数据库(MongoDB,Redis)

2018-09-05 14:40:40.854  INFO 12656 --- [    container-2] com.just.springbootnosql.Receiver        : receive message:我来自客户端

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/100280.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 智能点餐系统开发纪实2—–系统整体结构和业务流程「建议收藏」

    1请看这里http://blog.csdn.net/jason0539/article/details/20854329 写完之前这个就没写,趁着新鲜感几天就把这个弄完了,也没再写别的东西,前几天已经完成了,今天需要写一个文档,写完文档就把里面我写的部分贴到这里来了,有点罗嗦,凑字数。其实就是讲了一个整体流程,整个系统主要分四部分:小车,手机,收银台,厨房。服务器写了两个,收银

    2022年3月11日
    40
  • 免备案空间收集

    免备案空间收集用了这个国外的免备空间,觉得其他的都弱爆了此空间无广告,大空间,速度快,而且是即时开通的,我去截图分享下。虽然是美国的,但是提供中文申请页面,但是用谷歌浏览器可以无障碍设置。这是登录进去时候的页面:这个是我目前的两个域名,每过24小时可以创建一个。这个是控制面板这个是我的账户信息可以看一下磁盘容量和带宽,都是大到用不完···,跟其他的需要付神马1块两块钱别人才提供给…

    2022年6月18日
    21
  • Linux 修改用户密码「建议收藏」

    Linux 修改用户密码「建议收藏」Linux修改密码用passwd命令,用root用户运行passwd,passwduser_name可以设置或修改任何用户的密码,普通用户运行passwd只能修改它自己的密码。[root@localhost~]#passwd##修改root用户密码Changingpasswordforuserroot..Newpassword:##输入新密码Retypene…

    2022年6月3日
    107
  • Ti杯电子竞赛前期准备工作

    Ti杯电子竞赛前期准备工作标题竞赛时间和竞赛周期:1997年开始每二年举办-届,竞赛时间定于竞赛举办年度的9月份,赛期四天三夜(具体日期届时通知)。在双数的非竞赛年份,组织开展全国的专题性竞赛。竞赛方式:全国统一-命题、分赛区组织的方式。采用“半封闭、相对集中”的组织方式进行。学生可查阅纸介或网络技术资料,队内学生集体商讨设计,分工负责、团结协作,以队为基本单位独立完成竞赛任务;竞赛期间不允许任何教师或其他…

    2022年5月7日
    92
  • typescript的泛型_泛型有什么用

    typescript的泛型_泛型有什么用泛型指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定具体类型的一种特性。引入下面创建一个函数,实现功能:根据指定的数量count和数据value,创建一个包

    2022年7月31日
    6
  • Python使用pip安装/卸载包「建议收藏」

    Python使用pip安装/卸载包「建议收藏」不一定需要专业编辑器,原生Python也能安装包,使用pip就可以了。1、首先确认电脑上已安装的Python有无pip程序。打开Python文件所在的位置,“Scripts”文件夹,查看。2、若无pip,则到官方下载最新版Python安装包,运行安装包,Python会自动升级,升级完毕后再次查看,pip程序已经存在了。Python官方下载地址进入某一个版本的下载页面,根据自己的需要下载…

    2022年10月16日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号