springboot自定義redis-starter的實(shí)現(xiàn)
spring時(shí)代整合redis
spring我相信只要是一個(gè)Java開發(fā)人員我相信再熟悉不過(guò)了,幾乎壟斷了整個(gè)JavaEE的市場(chǎng)份額,話不多說(shuō)進(jìn)入正題。
首先看看我們?cè)趕pring中整合redis需要做什么
1、首先maven工程的話不用想先導(dǎo)入依賴
<!-- jedis --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.4.2</version> </dependency> <!-- 2、spring整合Redis的jar包 --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.4.2.RELEASE</version> </dependency>
2、在spring-xml中配置
<!-- 1、配置jedis連接池信息 --> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <!-- 最大連接數(shù)--> <property name="maxTotal" value="50"></property> <property name="maxIdle" value="5"></property> ....... 這里省略一些更多配置 </bean> <!--2、配置連接工廠JedisConnectionFactory--> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <!--需要自定義一些工廠屬性配置信息--> <!-- 服務(wù)器地址 --> <property name="hostName" value="127.0.0.1"></property> <!-- 服務(wù)端口號(hào) --> <property name="port" value="6379"></property> <!-- 密碼 --> <property name="password" value="yichun"></property> <!-- 連接池配置:再把第一步配置好的連接池信息通過(guò)屬性注入進(jìn)來(lái) 否則會(huì)采用默認(rèn)的連接池--> <property name="poolConfig" ref="jedisPoolConfig"></property> </bean> <!-- 3、配置RedisTemplate模板 把第二步配置好的連接工廠JedisConnectionFactory通過(guò)屬性注入到RedisTemplate模板中--> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> <property name="connectionFactory" ref="jedisConnectionFactory"></property> <!-- 配置一些key和value的序列化操作,可選操作 --> <property name="keySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean> </property> <property name="valueSerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean> </property> </bean> 4、這樣子以后我們就可以在業(yè)務(wù)層通過(guò) @Autowired 引用redis操作模板了 @Autowired RedisTemplate<String,String> redisTemplate;
3、上面就是spring使用redis的大致流程。
這樣子看起來(lái)也還好啊?
但是每個(gè)項(xiàng)目都要去經(jīng)過(guò)這么一系列繁瑣的xml配置,這就是重復(fù)工作了。這時(shí)候就出現(xiàn)了“springboot” 就是專門去做這些整合的事情了,讓我們不需要整合這些只需幾行基礎(chǔ)配置即可。
springboot 實(shí)現(xiàn)自動(dòng)裝配redis
在開始spring boot之前我們首先要來(lái)看幾個(gè)注解,spring boot實(shí)現(xiàn)自定義裝配的核心就是這幾個(gè)注解:
1、@Import:Import注解的主要的作用是將bean導(dǎo)入到spring容器中,比如說(shuō)要自定義一些bean交spring容器托管,這是我們就可以建一個(gè)配置類使用import注解專門去導(dǎo)入你自定義的一些bean到spring容器中。
2、@Bean:Bean注解告訴Spring這個(gè)方法將會(huì)返回一個(gè)對(duì)象,這個(gè)對(duì)象要注冊(cè)為Spring應(yīng)用上下文中的bean。通常方法體中包含了最終產(chǎn)生bean實(shí)例的邏輯。
3、@Component:通常是通過(guò)類路徑掃描來(lái)自動(dòng)偵測(cè)以及自動(dòng)裝配到Spring容器中。
4、@Configuration:來(lái)聲明一個(gè)spring的配置類等同于spring中的xml文件,ConfigurationClassPostProcessor::enhanceConfigurationClasses這個(gè)方法是Configuration注解工作的核心方法,spring應(yīng)用啟動(dòng)時(shí)所有的被@Configuration注解的類都會(huì)被spring cglib庫(kù)生成cglib動(dòng)態(tài)代理,然后其他地方通過(guò)@Autowired注解引入Student類對(duì)象就會(huì)被生成的configuration配置類生成的動(dòng)態(tài)代理攔截,處理完后再調(diào)用原configuration注解類的student方法獲取到Student實(shí)例。
5、@Conditiona:個(gè)人感覺(jué)主要是做一些判斷條件的、只有當(dāng)condition的machet匹配方法為 true 的時(shí)候【該方法內(nèi)也是我們實(shí)現(xiàn)一些自定義邏輯判斷的擴(kuò)展點(diǎn)】,才會(huì)去加載該bean 否則不加載該bean。
----- condition又繁衍出很多子類(方便我們直接使用)
@ConditionalOnMissingBean:當(dāng)容器下有當(dāng)前這個(gè)bean就不加載沒(méi)有則加載
@ConditionalOnExpression:當(dāng)括號(hào)中的內(nèi)容為true時(shí),使用該注解的類被實(shí)例化。
示例:
@ConditionalOnExpression("KaTeX parse error: Expected 'EOF', got '&' at position 25: …mer.enabled}==1&̲&{rabbitmq.comsumer.enabled:true}")
@ConditionalOnExpression("'${mq.comsumer}'.equals(‘rabbitmq')")
@ConditionalOnClass:當(dāng)classpath下有某個(gè)class的時(shí)候,就執(zhí)行下面操作
@ConditionalOnBean:只有當(dāng)給定的bean存在時(shí)、則實(shí)例化當(dāng)前bean。
1、新建兩個(gè)項(xiàng)目:一個(gè)autoconfig一個(gè)starter項(xiàng)目
注:【maven項(xiàng)目即可】。
starter:主要是做讓其他項(xiàng)目依賴的start。
autoconfig:實(shí)現(xiàn)具體自動(dòng)裝配邏輯處理。
2、添加 autoconfig 項(xiàng)目中的pom文件如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.xing.modules</groupId> <artifactId>spring-boot-redis-autoconfig</artifactId> <version>1.0.0</version> <properties> <!-- Environment Settings --> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <jedis.version>2.9.0</jedis.version> <springboot.version>2.1.4.RELEASE</springboot.version> </properties> <dependencies> <!-- springboot-stater --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>${springboot.version}</version> </dependency> <!-- spring-data-redis --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>${springboot.version}</version> </dependency> <!-- Jedis --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>${jedis.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure-processor</artifactId> <version>${springboot.version}</version> <optional>true</optional> </dependency> </dependencies> </project>
3、starter 項(xiàng)目中pom 只需添加autoconfig依賴即可。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.xing.modules</groupId> <artifactId>spring-boot-redis-starter</artifactId> <version>1.0.0</version> <properties> <!-- Environment Settings --> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties> <dependencies> <dependency> <groupId>org.xing.modules</groupId> <artifactId>spring-boot-redis-autoconfig</artifactId> <version>1.0.0</version> </dependency> </dependencies> </project>
4、autoconfig項(xiàng)目中創(chuàng)建一個(gè)包c(diǎn)onfiguration、再創(chuàng)建一個(gè)RedisConfiguration類。
package org.xing.modules.configuration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisOperations; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; import java.net.ConnectException; /** * {@like @ConditionalOnClass: * This annotation indicates that there must be RedisOperations in the current classpath to inject this Bean} * * @ConditionalOnClass(Jedis.class) * 此注解表示當(dāng)前ClassPath必須包含有Jedis這個(gè)類才會(huì)入這個(gè)配置類到spring容器中 * 意思就是項(xiàng)目當(dāng)中存在了jedis客戶端依賴才覺(jué)得你需要使用,否則就沒(méi)必要去注入. * * @author Created by John on 2020/10/12 */ @Configuration @ConditionalOnClass(Jedis.class) public class RedisConfiguration { // 加載配置文件信息 這里使用properties類去做配置加載。 // @src = org.xing.modules.configuration.RedisProperties 【**如下步驟 跟 spring 配置流程雷同**】 /** * <!-- 1、配置jedis連接池信息 --> * <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> * <property name="maxTotal" value="50"></property> * <property name="maxIdle" value="5"></property> * </bean> */ @Bean public JedisPool jedisPool(RedisProperties redisProperties) throws ConnectException { JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setMinIdle(redisProperties.getMinIdle()); jedisPoolConfig.setMaxIdle(redisProperties.getMaxIdle()); jedisPoolConfig.setMaxWaitMillis(redisProperties.getMaxWait()); jedisPoolConfig.setMaxTotal(redisProperties.getMaxActive()); String password = isBlank(redisProperties.getPassword()) ? null:redisProperties.getPassword(); return new JedisPool(jedisPoolConfig,redisProperties.getHost(),redisProperties.getPort(),redisProperties.getTimeout(),password); } /** <!--2、配置連接工廠JedisConnectionFactory--> * <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> * <!-- 服務(wù)器地址 --> * <property name="hostName" value="127.0.0.1"></property> * <!-- 服務(wù)端口號(hào) --> * <property name="port" value="6379"></property> * <!-- 密碼 --> * <property name="password" value="yichun"></property> * <!-- 連接池配置:再把第一步配置好的連接池信息通過(guò)屬性注入進(jìn)來(lái) 否則會(huì)采用默認(rèn)的連接池--> * <property name="poolConfig" ref="jedisPoolConfig"></property> * </bean> */ @Bean public JedisConnectionFactory redisConnectionFactory(RedisProperties redisProperties) { JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(); jedisConnectionFactory.setHostName(redisProperties.getHost()); jedisConnectionFactory.setPort(redisProperties.getPort()); jedisConnectionFactory.setPassword(redisProperties.getPassword()); jedisConnectionFactory.setDatabase(redisProperties.getDatabase()); return jedisConnectionFactory; } // 第三步抽離出:@src = org.xing.modules.template.RedisTemplateConfiguration /** <!-- 3、配置RedisTemplate模板 把第二步配置好的連接工廠JedisConnectionFactory通過(guò)屬性注入到RedisTemplate模板中--> * <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> * <property name="connectionFactory" ref="jedisConnectionFactory"></property> * * <!-- 配置一些key和value的序列化操作,可選操作 --> * <property name="keySerializer"> * <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean> * </property> * <property name="valueSerializer"> * <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean> * </property> * </bean> */ public static boolean isBlank(String str) { return str == null || "".equals(str.trim()); } }
5、創(chuàng)建properties配置文件加載類
package org.xing.modules.configuration; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; /** * @author Created by mr_zhou on 2020/10/12 * * @TODO: "my.springboot.redis" Qualified redis configuration must begin with this prefix * 限定使用此starter的redis配置必須以“my.springboot.redis.”為前綴 * 示例: * my.springboot.redis.host * my.springboot.redis.prot */ @Component @ConfigurationProperties(prefix = "my.springboot.redis") public class RedisProperties { private int port; private String host; private String password; private int timeout; private int database; @Value("${redis.pool.max-active}") private int maxActive; @Value("${redis.pool.max-wait}") private int maxWait; @Value("${redis.pool.max-idle}") private int maxIdle; @Value("${redis.pool.min-idle}") private int minIdle; // 省略 get/set方法
6、創(chuàng)建redis操作模板類
這里其實(shí)也可以 RedisConfiguration 類中注入到spring容器中,但是為了職責(zé)劃分就單獨(dú)使用。
package org.xing.modules.template; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; /** * TODO: Redis Template Configuration Class * * @author Created by mr_zhou on 2020/10/12 */ @Configuration public class RedisTemplateConfiguration { @Bean @ConditionalOnMissingBean public RedisTemplate redisTemplate(JedisConnectionFactory jedisConnectionFactory){ RedisTemplate redisTemplate = new RedisTemplate(); redisTemplate.setConnectionFactory(jedisConnectionFactory); return redisTemplate; } // 更多模板注入..... }
7、Redis對(duì)外出口配置類
該類主要作用于spring容器加載入口
package org.xing.modules.template; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; /** * TODO: Redis Template Configuration Class * * @author Created by mr_zhou on 2020/10/12 */ @Configuration public class RedisTemplateConfiguration { @Bean @ConditionalOnMissingBean public RedisTemplate redisTemplate(JedisConnectionFactory jedisConnectionFactory){ RedisTemplate redisTemplate = new RedisTemplate(); redisTemplate.setConnectionFactory(jedisConnectionFactory); return redisTemplate; } // 更多模板注入..... }
8、springboot優(yōu)雅擴(kuò)展的入口
我們打開springboot自動(dòng)配置jar里面的源碼:
springboot自動(dòng)裝配主要是掃描
【META-INF 下的 spring.factories 文件下 # Auto Configure】下的所有類
因此我們照葫蘆畫瓢【在starter下創(chuàng)建META-INF 再創(chuàng)建spring.factories】
讓后在maven里面先后 autoconfig -> starter install一下。
9、demo使用自定義starter
1、在demo項(xiàng)目中加入自定義starter的依賴
2、最后就可以直接在項(xiàng)目中注入使用redis。
【pom里面可以看到我們沒(méi)有加任何redis依賴的只加了自定義的starter】
/** * @author Created by mr_zhou on 2020/10/12 */ public class MyService { @Autowired private RedisTemplate redisTemplate; }
3、配置redis連接信息即可操作 - 對(duì)應(yīng) RedisProperties 屬性。
10、全劇終
最后我們就可以慢慢完善自己的starter做到以后直接使用自己的redis封裝一些常用的操作。
到此這篇關(guān)于springboot自定義redis-starter的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)springboot自定義redis-starter內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- spring boot 自定義starter的實(shí)現(xiàn)教程
- springboot自定義Starter的具體流程
- Spring boot創(chuàng)建自定義starter的完整步驟
- spring boot微服務(wù)自定義starter原理詳解
- springboot自定義starter實(shí)現(xiàn)過(guò)程圖解
- SpringBoot自動(dòng)配置之自定義starter的實(shí)現(xiàn)代碼
- 使用SpringBoot自定義starter的完整步驟
- Java SpringBoot自定義starter詳解
- SpringBoot如何自定義starter
- SpringBoot自定義start詳細(xì)圖文教程
相關(guān)文章
java中對(duì)字符串每個(gè)字符統(tǒng)計(jì)的方法
java中對(duì)字符串每個(gè)字符統(tǒng)計(jì)的方法,需要的朋友可以參考一下2013-03-03從內(nèi)存地址解析Java的static關(guān)鍵字的作用
這篇文章主要介紹了從內(nèi)存地址解析Java的static關(guān)鍵字的作用,包括靜態(tài)成員變量和靜態(tài)方法等重要內(nèi)容,需要的朋友可以參考下2015-10-10Java Socket實(shí)現(xiàn)單線程通信的方法示例
這篇文章主要介紹了Java Socket實(shí)現(xiàn)單線程通信的方法,結(jié)合具體實(shí)例形式分析了java socket單線程通信的原理與客戶端、服務(wù)器端相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-06-06JVM分配和回收堆外內(nèi)存的方式與注意點(diǎn)
JVM啟動(dòng)時(shí)分配的內(nèi)存稱為堆內(nèi)存,與之相對(duì)的,在代碼中還可以使用堆外內(nèi)存,比如Netty,廣泛使用了堆外內(nèi)存,下面這篇文章主要給大家介紹了關(guān)于JVM分配和回收堆外內(nèi)存的方式與注意點(diǎn),需要的朋友可以參考下2022-07-07MyBatis接口的簡(jiǎn)單實(shí)現(xiàn)原理分析
這里僅僅舉個(gè)簡(jiǎn)單例子來(lái)說(shuō)明原理,不是完全針對(duì)MyBatis的,這種思想我們也可以應(yīng)用在其他地方。地mybatis接口實(shí)現(xiàn)原理感興趣的朋友一起看看吧2017-07-07Springboot Activemq整合過(guò)程代碼圖解
這篇文章主要介紹了Springboot Activemq整合過(guò)程代碼圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02