在搭建基於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 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;
/**
*
* @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層里面可以直接。
