隐藏

基于IDEA搭建springboot+redis环境,深入了解相关机制

发布:2022/3/3 16:02:51作者:管理员 来源:本站 浏览次数:844

本文主要目的在搭建基于IDEA的springboot+Redis环境时,深入了解springboot框架的相关机制,了解何时用配置文件,何时利用注解,尽可能清晰、完备的总结相关核心问题。

话不多少,进入主题。

1、搭建springboot+redis的方式有两种,它们分别如下:

方式一:基于RedisTemplate类  ,redisTemplate是springdate提供的管理redis的工具,springboot可以直接注入。

需要安装依赖:

    <!-- springboot整合redis -->
     
    <dependency>
     
            <groupId>org.springframework.boot</groupId>
     
            <artifactId>spring-boot-starter-data-redis</artifactId>
     
    </dependency>

  方式二:基于jedis  ,Jedis是Redis官方推荐的面向Java的操作Redis的客户端,jedis不需要注入直接调用就可以,如果想注入到spring中的话,需要创建jedis配置文件,配置文件的作用是在项目启动的时候将jedis注入,接着我们就可以在其他类中获取到JedisPool类的信息。

需要安装的依赖:

    <!-- redis -->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
    </dependency>

  本项目采用的方式是基于方法二,即利于jedis,通过创建jedis配置文件的方式,注入jedisPool类信息。

2、项目架构如下所示:

3、从项目正常启动开始说明各个文件的作用以及相关配置说明

a》pom.xml内容   主要是添加redis jar

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
     
        <!-- redis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
     
        <!-- Log4J -->
        <!-- https://mvnrepository.com/artifact/log4j/log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
     
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

b》本项目还是采用的springboot的默认配置文件--application.properties,配置文件里面主要配置的是tomcat的端口(默认是8080,本项目改成9999,如果tomcat的端口默认是8080,就不需要增加server.port的配置了),以及redis的相关配置。

注意:springboot的版本不同,相应redis的配置也不同。redis的pool属性在springboot版本1.4后,该属性就被封装到jedis中了。本项目springboot的版本是2.0.4,因此配置如下:

    server.port=9999
    #redis
    spring.redis.hostName=132.232.28.164
    spring.redis.port=6379    
    #springboot版本为2.0.2RELEASE中的RedisProperties配置文件类,从图中可知pool属性则被封装到了内部静态类Jedis和Lettuce中去了
    spring.redis.jedis.pool.max-active=8
    # 连接池最大阻塞等待时间(使用负值表示没有限制)
    spring.redis.jedis.pool.max-wait=-1
    # 连接池中的最大空闲连接
    spring.redis.jedis.pool.max-idle=8
    # 连接池中的最小空闲连接
    spring.redis.jedis.pool.min-idle=0
    # 连接超时时间(毫秒)
    spring.redis.timeout=0

c》jedis的配置类config-->RedisConfig.java

正面最开始介绍的,jedis不需要注入直接调用就可以,如果想注入到spring中的话,需要创建jedis配置文件,配置文件的作用是在项目启动的时候将jedis注入,接着我们就可以在其他类中获取到JedisPool类的信息。

RedisConfig.java内容如下:

    package com.xz.spring_redis.config;
     
    import org.apache.log4j.Logger;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.stereotype.Component;
    import redis.clients.jedis.JedisPool;
    import redis.clients.jedis.JedisPoolConfig;
     
    /**
     *
     * @author vic
     * @desc redis config bean
     *
     */
    @Component//spring boot1.5以上版本@ConfigurationProperties取消location注解后的替代方案 cannot resolve method location   与@EnableConfigurationProperties是替代关系
    //没有使用@Component或@Confinguration,因此此对象不会注册到Spring容器中,需要@EnableConfigurationProperties
    @PropertySource("classpath:application.properties")//使用@PropertySource来指定自定义的资源目录
    @ConfigurationProperties(prefix = "spring.redis") //读取application.properties文件中以“spring.redis”开头的变量值。
    public class RedisConfig {
     
        private static Logger logger = Logger.getLogger(RedisConfig.class);
     
        private String hostName;
     
        private int port;
     
        //private String password;
     
        private int timeout;
     
     
        //@Bean    //此处注入JedisPoolConfig对象没有意义,不需要
        public JedisPoolConfig getRedisConfig(){
            JedisPoolConfig config = new JedisPoolConfig();
            return config;
        }
     
        @Bean//@Bean注解将一个配置类的方法的返回值定义为一个bean,注册到spring里面
        public JedisPool getJedisPool(){
            JedisPoolConfig config = getRedisConfig();
            JedisPool pool = new JedisPool(config,hostName,port);
            logger.info("init JredisPool ...");
            return pool;
        }
     
        public String getHostName() {
            return hostName;
        }
     
        public void setHostName(String hostName) {
            this.hostName = hostName;
        }
     
        public int getPort() {
            return port;
        }
     
        public void setPort(int port) {
            this.port = port;
        }
        /**
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }
         **/
     
        public int getTimeout() {
            return timeout;
        }
     
        public void setTimeout(int timeout) {
            this.timeout = timeout;
        }
     
    }

首先理解

        1、这个配置类的目的就是往spring里面注册JedisPool实例,方便其他地方Autowired JedisPool对象;

        2、配置类中几个注解的意思:

       @ConfigurationProperties:

    1、@ConfigurationProperties(prefix = "spring.redis") //读取application.properties文件中以“spring.redis”开头的变量值。
    2、@ConfigurationProperties和@value都是将外部属性注入到对象
    3、@ConfigurationProperties很方便使用。 比用@value注解好吗? 在特定的方案中是的,这只是一个选择问题

      @PropertySource:

@PropertySource("classpath:application.properties")//使用@PropertySource来指定自定义的资源目录

       @Component注解意思:

                   将类定义为一个bean的注解。比如 @Component,@Service,@Controller,@Repository

       @EnableConfigurationProperties:

      1、如果没有 @Component,@Service,@Controller,@Repository这几个注解,则可以通过@EnableConfigurationProperties,来定义为bean  。

      2、@EnableConfigurationProperties //开启属性注入,有此注解就可以通过@autowired注入, 是配合@ConfigurationProperties使用的。如果没有@EnableConfigurationProperties,则使用@ConfigurationProperties注解的class上面还需要添加@Component(@Component的包装注解,譬如@Configuration、@Service也可以。但本质还是注解@Component)。

      3、@EnableAutoConfiguration在Spring boot中是启动自动配置的(Auto-configuration tries to be as intelligent as possible and will back-away as you define more of your own configuration.)。

 

   redis配置类中目的都是通过@ConfigurationProperties使用外部配置填充Bean属性的几种方法,即通过获取application.properties里面的变量值来填充配置类中的Bean属性。

      具体有如下几种方式:         

    方式1 : @ConfigurationProperties + @Component 注解到bean定义类上
    方式2 : @ConfigurationProperties + @Bean注解在配置类的bean定义方法上
    方式3 : @ConfigurationProperties注解到普通类然后通过@EnableConfigurationProperties定义为bean

    资料来源:https://blog.csdn.net/andy_zhang2007/article/details/78761651

     重点讲解下方式二,因为本项目用的方式就是这种,具体讲解如下:

    @Component :说明该类是bean

    @PropertySource("classpath:application.properties"):指定springboot配置文件的路径

    @ConfigurationProperties(prefix = "spring.redis") :从springboot默认配置文件(application.properties)文件中读取变量值,然后赋值给hostname,port,timeout三个变量(当然可以读取更多变量)

    //@Bean    //此处注入JedisPoolConfig对象没有意义,不需要
    public JedisPoolConfig getRedisConfig(){
        JedisPoolConfig config = new JedisPoolConfig();
        return config;
    }
     
    @Bean//@Bean注解将一个配置类的方法的返回值定义为一个bean,注册到spring里面
    public JedisPool getJedisPool(){
        JedisPoolConfig config = getRedisConfig();
        JedisPool pool = new JedisPool(config,hostName,port);
        logger.info("init JredisPool ...");
        return pool;
    }

   @bean注解放置在配置类中方法面前,就是说明这个方法返回的对象定义为一个bean,注册到spring 里面,这样做的好处是避免二次加载application.xml文件。(资料:https://www.cnblogs.com/s648667069/p/6489557.html,很重要!!!)例如getJedisPool方法返回的是一个jedispool对象,注册为bean,后面service层里面可以直接

    @Autowired
    private JedisPool jedisPool;

   但是getRedisConfig方法就没必要加上@bean注解,因为后面不需要自动注入这个对象。

 

d》service层  --->RedisService.java和RedisServiceImpl.java

RedisService.java:接口类,定义redis的一些方法

    package com.xz.spring_redis.service;
    import redis.clients.jedis.Jedis;
     
     
    public interface RedisService {
     
        public Jedis getResource();
     
        public void returnResource(Jedis jedis);
     
        public void set(String key, String value);
     
        public String get(String key);
    }

RedisServiceImpl.java:实现类,实现redis的一些方法

    package com.xz.spring_redis.service;
     
    import org.apache.log4j.Logger;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisPool;
     
    /**
     *
     * @author vic
     * @desc resdis service
     *
     */
    @Service
    public class RedisServiceImpl implements RedisService {
     
        private static Logger logger = Logger.getLogger(RedisServiceImpl.class);
     
        @Autowired
        private JedisPool jedisPool;    //jedisPool不属于springboot框架支持的redis类,所以需要自行注入到spring中。通过配置类RedisConfig类注入的
     
        @Override
        public Jedis getResource() {
            return jedisPool.getResource();
        }
     
        @SuppressWarnings("deprecation")
        @Override
        public void returnResource(Jedis jedis) {
            if(jedis != null){
                jedisPool.returnResourceObject(jedis);
            }
        }
     
        @Override
        public void set(String key, String value) {
            Jedis jedis=null;
            try{
                jedis = getResource();
                jedis.set(key, value);
                logger.info("Redis set success - " + key + ", value:" + value);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("Redis set error: "+ e.getMessage() +" - " + key + ", value:" + value);
            }finally{
                returnResource(jedis);
            }
        }
     
        @Override
        public String get(String key) {
            String result = null;
            Jedis jedis=null;
            try{
                jedis = getResource();
                result = jedis.get(key);
                logger.info("Redis get success - " + key + ", value:" + result);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("Redis set error: "+ e.getMessage() +" - " + key + ", value:" + result);
            }finally{
                returnResource(jedis);
            }
            return result;
        }
     
    }

e》controller--》DemoController.java,能Autowired  RedisService的原因是该类上加入了@service注解,表示为bean

    package com.xz.spring_redis.controller;
     
    import com.xz.spring_redis.model.ResponseModal;
    import com.xz.spring_redis.service.RedisService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
     
    @RestController
    public class DemoController {
     
        @Autowired
        private RedisService redisService;
     
     
        @RequestMapping("/redis/set")
        public ResponseModal redisSet(@RequestParam("value")String value){
            redisService.set("name", value);
            return new ResponseModal(200, true, "success", null);
        }
     
        @RequestMapping("/redis/get")
        public ResponseModal redisGet(){
            String name = redisService.get("name");
            return new ResponseModal(200, true,"success",name);
        }
     
     
    }

f》model  都是与视图相关的数据,定义消息返回格式

Model.java

    package com.xz.spring_redis.model;
     
    public class Modal {
       
     
       public Modal() {
          super();
       }
     
       public Modal(int code, boolean success, String message) {
          super();
          this.code = code;
          this.success = success;
          this.message = message;
       }
     
       private int code;
       
       private boolean success;
       
       private String message;
     
       public int getCode() {
          return code;
       }
     
       public void setCode(int code) {
          this.code = code;
       }
     
       public boolean isSuccess() {
          return success;
       }
     
       public void setSuccess(boolean success) {
          this.success = success;
       }
     
       public String getMessage() {
          return message;
       }
     
       public void setMessage(String message) {
          this.message = message;
       }
       
    }

ResponseModal.java

    package com.xz.spring_redis.model;
     
    import java.io.Serializable;
     
    public class ResponseModal extends Modal implements Serializable{
     
       private static final long serialVersionUID = 1L;
       
       public ResponseModal(){
          super();
       }
       
       public ResponseModal(int code,boolean success,String message){
          super(code,success,message);
       }
       
       public ResponseModal(int code,boolean success,String message,Object obj){
          super(code,success,message);
          this.response = obj;
       }
       
       private Object response;
     
       public Object getResponse() {
          return response;
       }
     
       public void setResponse(Object response) {
          this.response = response;
       }
       
    }

g》启动类  没有进行任何修改(因为service层,controller层里面都添加了@service和@controller注解,所以不需要添加@EnableConfigurationProperties,另外因为不涉及到dao层或mapper层的操作,所以没有用到@MapperScanner注解扫描mapper包)

    package com.xz.spring_redis;
     
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
     
    @SpringBootApplication
    public class SpringRedisApplication {
     
        public static void main(String[] args) {
            SpringApplication.run(SpringRedisApplication.class, args);
        }
    }

4、至此项目要点讲解完毕。总结一下:

1)关于redis的maven配置问题,有两种方式:

     方式一:基于RedisTemplate类  ,redisTemplate是springdate提供的管理redis的工具,springboot可以直接注入。

     方式二:基于jedis  ,Jedis是Redis官方推荐的面向Java的操作Redis的客户端,jedis不需要注入直接调用就可以,如果想注入到spring中的话,需要创建jedis配置文件,配置文件的作用是在项目启动的时候将jedis注入,接着我们就可以在其他类中获取到JedisPool类的信息。

(2)application.properties配置中,springboot的版本不同,相应redis的配置也不同。redis的pool属性在springboot版本1.4后,该属性就被封装到jedis中了。

(3)几种注解的意思

       @ConfigurationProperties:

               1、@ConfigurationProperties(prefix = "spring.redis") //读取application.properties文件中以“spring.redis”开头的变量值。        2、@ConfigurationProperties和@value都是将外部属性注入到对象  

               3、@ConfigurationProperties很方便使用。 比用@value注解好吗? 在特定的方案中是的,这只是一个选择问题

      @PropertySource:

@PropertySource("classpath:application.properties")//使用@PropertySource来指定自定义的资源目录

       @Component注解意思:

                   将类定义为一个bean的注解。比如 @Component,@Service,@Controller,@Repository

       @EnableConfigurationProperties:

      1、如果没有 @Component,@Service,@Controller,@Repository这几个注解,则可以通过@EnableConfigurationProperties,来定义为bean  。

      2、@EnableConfigurationProperties //开启属性注入,有此注解就可以通过@autowired注入, 是配合@ConfigurationProperties使用的。如果没有@EnableConfigurationProperties,则使用@ConfigurationProperties注解的class上面还需要添加@Component(@Component的包装注解,譬如@Configuration、@Service也可以。但本质还是注解@Component)。

      3、@EnableAutoConfiguration在Spring boot中是启动自动配置的(Auto-configuration tries to be as intelligent as possible and will back-away as you define more of your own configuration.)。

(4)配置类中@bean放在方法面前的作用

         就是说明这个方法返回的对象定义为一个bean,注册到spring 里面,这样做的好处是避免二次加载application.xml文件。(资料:https://www.cnblogs.com/s648667069/p/6489557.html,很重要!!!)例如getJedisPool方法返回的是一个jedispool对象,注册为bean,后面service层里面可以直接。

 

5、项目源代码:https://github.com/xia123zheng/springboot_redis