Spring Boot 自定義starter和autoconfigure
一、spring-data-redis本來的自動配置怎麼用:
我們只需要引入spring-boot-starter-data-redis包就可以使用redis了,不用關心其他依賴的包
這個包中會把我們需要的其他包一起引入
看spring-data-redis中原始碼的自定義配置
可以知道,它給redis自動配置了一些預設屬性,如:
maxActive = 8
maxIdle = 8
minIdle = 0
maxWait = -1
然後我們在引入了autoconfigure和spring-boot-starter-data-redis後,這些預設配置會自動到redis的連線池配置中。如果需要修改指定值,則在application.yml中配置
spring:
redis:
database: 0
host: 192.168.2.240
password: 456987
port: 6379
pool:
maxActive: 60
maxIdle: 60
maxWait: 3000
application.yml沒有配置,則Redis的配置用原始碼中自動配置的屬性,如果application.yml有配置,則會被application.yml中的配置覆蓋。比如:沒有application.yml,則maxToal=8,有application.yml,則maxActive=60
二、自定義starter和autoconfigure
使用場景:
工作中有接到如下需求:
1.封裝apache http client ,讓業務開發的組可以開箱即用,不用關心配置。(這個不介紹,類似的)
2.封裝redis,讓業務開發組開箱即用,不用關心連線池的配置。這裡就有個問題了,spring-data-redis已經做了自動配置了,為什麼還要再封裝,因為spring-data-redis做的自動配置的那些屬性,跟我們期待的標準配置太不一樣了。
比如,我們期待的預設配置是
private int maxIdle = 60; private int minIdle = 0; private int maxActive = 60; private int maxWait = 3000; private boolean testOnCreate = false; private boolean testOnBorrow = false; private boolean testOnReturn = false; private boolean testWhileIdle = true; private long minEvictableIdleTimeMillis = 70000; private long timeBetweenEvictionRunsMillis = 40000; private int numTestsPerEvictionRun = -1;
各個業務系統根據實際情況,自己還可以再改。
建立一個專案common-redis-spring-boot
在這個專案中建立兩個modules
common-redis-spring-boot-autoconfigure
common-redis-spring-boot-starter
結構如下
1.common-redis-spring-boot
這個工程中不要引入掃描相關的註解,如@Autowire, @componet, @Service, @Controller等
這個工程主要定義子模組的需要用到的jar。
pom.xml
<?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>com.sid</groupId>
<artifactId>common-redis-spring-boot</artifactId>
<!-- 父模組必須以pom方式打包 -->
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
<spring-boot.version>1.5.8.RELEASE</spring-boot.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<common-redis.springboot.verison>1.0-SNAPSHOT</common-redis.springboot.verison>
<common-redis.version>1.0-SNAPSHOT</common-redis.version>
</properties>
<!-- 定義兩個子模組 -->
<modules>
<module>common-redis-spring-boot-autoconfigure</module>
<module>common-redis-spring-boot-starter</module>
</modules>
<!-- 定義子模組中需要的jar
所有使用dependencyManagement預先定義相關的jar和版本
保證在子類中需要使用時,只需要引入包,而不用使用版本號
-->
<dependencyManagement>
<dependencies>
<!-- spring boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>com.gs</groupId>
<artifactId>common-redis-spring-boot-autoconfigure</artifactId>
<version>${common-redis.springboot.verison}</version>
</dependency>
<!-- common-redis 自己寫的一個redis包 裡面全是靜態方法-->
<dependency>
<groupId>com.sid</groupId>
<artifactId>common-redis</artifactId>
<version>${common-redis.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
2.common-redis-spring-boot-autoconfigure
pom.xml
<?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">
<parent>
<artifactId>common-redis-spring-boot</artifactId>
<groupId>com.sid</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../../common-redis-spring-boot/pom.xml</relativePath>
</parent>
<properties>
<jackson.version>2.8.10</jackson.version>
</properties>
<modelVersion>4.0.0</modelVersion>
<artifactId>common-redis-spring-boot-autoconfigure</artifactId>
<dependencies>
<!-- @ConfigurationProperties annotation processing (metadata for IDEs)
生成spring-configuration-metadata.json類,需要引入此類
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<optional>true</optional>
</dependency>
<!-- spring-boot redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.sid</groupId>
<artifactId>common-redis</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
<optional>true</optional>
</dependency>
<!-- spring-boot 測試包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
spring-boot-configuration-processor 的作用是編譯時生成spring-configuration-metadata.json,在intellij idea中,當配置此jar相關配置屬性在application.properties,你可以用ctlr+滑鼠左鍵,IDE會跳轉到你配置此屬性的類中
MyRedisProperties.java 屬性類
自動從配置檔案中解析屬性並生成物件
package common.redis.spring.boot.autoconfigure.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.List;
/**
* @program: common-redis-spring-boot
* @description:
* @author: Sid
* @date: 2018-11-01 17:18
* @since: 1.0
**/
//注入application.yml中spring.redis開頭的屬性
/**
* 通過@EnableConfigurationProperties可以將被@ConfigurationProperties註解的類生成一個bean
* */
@ConfigurationProperties(prefix = "spring.redis")
public class MyRedisProperties {
/**
* Database index used by the connection factory.
*/
private int database = 0;
/**
* Redis url, which will overrule host, port and password if set.
*/
private String url;
/**
* Redis server host.
*/
private String host = "localhost";
/**
* Login password of the redis server.
*/
private String password;
/**
* Redis server port.
*/
private int port = 6379;
/**
* Enable SSL.
*/
private boolean ssl;
/**
* Connection timeout in milliseconds.
*/
private int timeout;
private Pool pool = new Pool();
private Sentinel sentinel;
private Cluster cluster;
public int getDatabase() {
return this.database;
}
public void setDatabase(int database) {
this.database = database;
}
public String getUrl() {
return this.url;
}
public void setUrl(String url) {
this.url = url;
}
public String getHost() {
return this.host;
}
public void setHost(String host) {
this.host = host;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
public int getPort() {
return this.port;
}
public void setPort(int port) {
this.port = port;
}
public boolean isSsl() {
return this.ssl;
}
public void setSsl(boolean ssl) {
this.ssl = ssl;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
public int getTimeout() {
return this.timeout;
}
public Sentinel getSentinel() {
return this.sentinel;
}
public void setSentinel(Sentinel sentinel) {
this.sentinel = sentinel;
}
public Pool getPool() {
return this.pool;
}
public void setPool(Pool pool) {
this.pool = pool;
}
public Cluster getCluster() {
return this.cluster;
}
public void setCluster(Cluster cluster) {
this.cluster = cluster;
}
/**
* Pool properties.
*/
public static class Pool {
/**
* Max number of "idle" connections in the pool. Use a negative value to indicate
* an unlimited number of idle connections.
*/
private int maxIdle = 60;
/**
* Target for the minimum number of idle connections to maintain in the pool. This
* setting only has an effect if it is positive.
*/
private int minIdle = 0;
/**
* Max number of connections that can be allocated by the pool at a given time.
* Use a negative value for no limit.
*/
private int maxActive = 60;
/**
* Maximum amount of time (in milliseconds) a connection allocation should block
* before throwing an exception when the pool is exhausted. Use a negative value
* to block indefinitely.
*/
private int maxWait = 3000;
private boolean testOnCreate = false;
private boolean testOnBorrow = false;
private boolean testOnReturn = false;
private boolean testWhileIdle = true;
private long minEvictableIdleTimeMillis = 60000;
private long timeBetweenEvictionRunsMillis = 30000;
private int numTestsPerEvictionRun = -1;
public int getMaxIdle() {
return this.maxIdle;
}
public void setMaxIdle(int maxIdle) {
this.maxIdle = maxIdle;
}
public int getMinIdle() {
return this.minIdle;
}
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
public int getMaxActive() {
return this.maxActive;
}
public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
}
public int getMaxWait() {
return this.maxWait;
}
public void setMaxWait(int maxWait) {
this.maxWait = maxWait;
}
public boolean getTestOnCreate() {
return testOnCreate;
}
public void setTestOnCreate(boolean testOnCreate) {
this.testOnCreate = testOnCreate;
}
public boolean getTestOnBorrow() {
return testOnBorrow;
}
public void setTestOnBorrow(boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
}
public boolean getTestOnReturn() {
return testOnReturn;
}
public void setTestOnReturn(boolean testOnReturn) {
this.testOnReturn = testOnReturn;
}
public boolean getTestWhileIdle() {
return testWhileIdle;
}
public void setTestWhileIdle(boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
}
public long getMinEvictableIdleTimeMillis() {
return minEvictableIdleTimeMillis;
}
public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
}
public long getTimeBetweenEvictionRunsMillis() {
return timeBetweenEvictionRunsMillis;
}
public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
}
public int getNumTestsPerEvictionRun() {
return numTestsPerEvictionRun;
}
public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
this.numTestsPerEvictionRun = numTestsPerEvictionRun;
}
}
/**
* Cluster properties.
*/
public static class Cluster {
/**
* Comma-separated list of "host:port" pairs to bootstrap from. This represents an
* "initial" list of cluster nodes and is required to have at least one entry.
*/
private List<String> nodes;
/**
* Maximum number of redirects to follow when executing commands across the
* cluster.
*/
private Integer maxRedirects;
public List<String> getNodes() {
return this.nodes;
}
public void setNodes(List<String> nodes) {
this.nodes = nodes;
}
public Integer getMaxRedirects() {
return this.maxRedirects;
}
public void setMaxRedirects(Integer maxRedirects) {
this.maxRedirects = maxRedirects;
}
}
/**
* Redis sentinel properties.
*/
public static class Sentinel {
/**
* Name of Redis server.
*/
private String master;
/**
* Comma-separated list of host:port pairs.
*/
private String nodes;
public String getMaster() {
return this.master;
}
public void setMaster(String master) {
this.master = master;
}
public String getNodes() {
return this.nodes;
}
public void setNodes(String nodes) {
this.nodes = nodes;
}
}
}
RedisAutoConfig.java 自動配置類
package common.redis.spring.boot.autoconfigure;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.fastjson.JSON;
import common.redis.RedisUtil;
import common.redis.spring.boot.autoconfigure.properties.MyRedisProperties;
import common.redis.spring.boot.autoconfigure.properties.MyRedisProperties.Sentinel;
import common.redis.spring.boot.autoconfigure.properties.MyRedisProperties.Cluster;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnection;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import javax.annotation.PostConstruct;
/**
* @program: common-redis-spring-boot
* @description:
* @author: Sid
* @date: 2018-11-01 17:02
* @since: 1.0
**/
@Configuration //定義配置類
@AutoConfigureBefore(RedisAutoConfiguration.class)
@ConditionalOnClass({ JedisConnection.class, RedisOperations.class, Jedis.class })
@EnableConfigurationProperties(MyRedisProperties.class)
public class RedisAutoConfig {
/**
* Redis connection configuration.
*/
@Configuration
@ConditionalOnClass(GenericObjectPool.class)
protected static class RedisConnectionConfiguration {
private final MyRedisProperties properties;
private final RedisSentinelConfiguration sentinelConfiguration;
private final RedisClusterConfiguration clusterConfiguration;
public RedisConnectionConfiguration(MyRedisProperties properties,
ObjectProvider<RedisSentinelConfiguration> sentinelConfiguration,
ObjectProvider<RedisClusterConfiguration> clusterConfiguration) {
this.properties = properties;
this.sentinelConfiguration = sentinelConfiguration.getIfAvailable();
this.clusterConfiguration = clusterConfiguration.getIfAvailable();
}
@Bean
@ConditionalOnMissingBean(RedisConnectionFactory.class)
public JedisConnectionFactory redisConnectionFactory() {
return applyProperties(createJedisConnectionFactory());
}
protected final JedisConnectionFactory applyProperties(JedisConnectionFactory factory) {
configureConnection(factory);
if (this.properties.isSsl()) {
factory.setUseSsl(true);
}
factory.setDatabase(this.properties.getDatabase());
if (this.properties.getTimeout() > 0) {
factory.setTimeout(this.properties.getTimeout());
}
return factory;
}
private void configureConnection(JedisConnectionFactory factory) {
if (StringUtils.hasText(this.properties.getUrl())) {
configureConnectionFromUrl(factory);
}
else {
factory.setHostName(this.properties.getHost());
factory.setPort(this.properties.getPort());
if (this.properties.getPassword() != null) {
factory.setPassword(this.properties.getPassword());
}
}
}
private void configureConnectionFromUrl(JedisConnectionFactory factory) {
String url = this.properties.getUrl();
if (url.startsWith("rediss://")) {
factory.setUseSsl(true);
}
try {
URI uri = new URI(url);
factory.setHostName(uri.getHost());
factory.setPort(uri.getPort());
if (uri.getUserInfo() != null) {
String password = uri.getUserInfo();
int index = password.lastIndexOf(":");
if (index >= 0) {
password = password.substring(index + 1);
}
factory.setPassword(password);
}
}
catch (URISyntaxException ex) {
throw new IllegalArgumentException("Malformed 'spring.redis.url' " + url,
ex);
}
}
protected final RedisSentinelConfiguration getSentinelConfig() {
if (this.sentinelConfiguration != null) {
return this.sentinelConfiguration;
}
Sentinel sentinelProperties = this.properties.getSentinel();
if (sentinelProperties != null) {
RedisSentinelConfiguration config = new RedisSentinelConfiguration();
config.master(sentinelProperties.getMaster());
config.setSentinels(createSentinels(sentinelProperties));
return config;
}
return null;
}
/**
* Create a {@link RedisClusterConfiguration} if necessary.
* @return {@literal null} if no cluster settings are set.
*/
protected final RedisClusterConfiguration getClusterConfiguration() {
if (this.clusterConfiguration != null) {
return this.clusterConfiguration;
}
if (this.properties.getCluster() == null) {
return null;
}
Cluster clusterProperties = this.properties.getCluster();
RedisClusterConfiguration config = new RedisClusterConfiguration(
clusterProperties.getNodes());
if (clusterProperties.getMaxRedirects() != null) {
config.setMaxRedirects(clusterProperties.getMaxRedirects());
}
return config;
}
private List<RedisNode> createSentinels(Sentinel sentinel) {
List<RedisNode> nodes = new ArrayList<RedisNode>();
for (String node : StringUtils.commaDelimitedListToStringArray(sentinel.getNodes())) {
try {
String[] parts = StringUtils.split(node, ":");
Assert.state(parts.length == 2, "Must be defined as 'host:port'");
nodes.add(new RedisNode(parts[0], Integer.valueOf(parts[1])));
}
catch (RuntimeException ex) {
throw new IllegalStateException(
"Invalid redis sentinel " + "property '" + node + "'", ex);
}
}
return nodes;
}
private JedisConnectionFactory createJedisConnectionFactory() {
JedisPoolConfig poolConfig = this.properties.getPool() != null
? jedisPoolConfig() : new JedisPoolConfig();
if (getSentinelConfig() != null) {
return new JedisConnectionFactory(getSentinelConfig(), poolConfig);
}
if (getClusterConfiguration() != null) {
return new JedisConnectionFactory(getClusterConfiguration(), poolConfig);
}
return new JedisConnectionFactory(poolConfig);
}
private JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig config = new JedisPoolConfig();
MyRedisProperties.Pool props = this.properties.getPool();
config.setMaxTotal(props.getMaxActive());
config.setMaxIdle(props.getMaxIdle());
config.setMinIdle(props.getMinIdle());
config.setMaxWaitMillis(props.getMaxWait());
//sid since1.0 允許使用者自定義這幾個屬性
config.setTestOnCreate(props.getTestOnCreate());
config.setTestOnBorrow(props.getTestOnBorrow());
config.setTestOnReturn(props.getTestOnReturn());
config.setTestWhileIdle(props.getTestWhileIdle());
config.setMinEvictableIdleTimeMillis(props.getMinEvictableIdleTimeMillis());
config.setTimeBetweenEvictionRunsMillis(props.getTimeBetweenEvictionRunsMillis());
config.setNumTestsPerEvictionRun(props.getNumTestsPerEvictionRun());
return config;
}
}
/**
* Standard Redis configuration.
*/
@Configuration
protected static class RedisConfiguration {
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
template.setConnectionFactory(redisConnectionFactory);
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
template.afterPropertiesSet();
return template;
}
@Bean
@ConditionalOnMissingBean(StringRedisTemplate.class)
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
@Bean
@ConditionalOnBean(RedisTemplate.class)
public RedisUtilConfig redisUtilConfig() {
return new RedisUtilConfig();
}
public class RedisUtilConfig {
private final Logger logger = LoggerFactory.getLogger(RedisUtilConfig.class);
@Autowired
private RedisTemplate redisTemplate;
@PostConstruct
public void afterPropertiesSet() {
//往com.sid.common.redis中注入,這裡面封裝了各種靜態方法。
RedisUtil.init(redisTemplate);
JedisConnectionFactory connectionFactory = (JedisConnectionFactory) redisTemplate.getConnectionFactory();
logger.info("redisTemplate-->JedisConnectionFactory-->PoolConfig-->{}", JSON.toJSONString(connectionFactory.getPoolConfig(), true));
}
}
}
註解介紹
@Configuration:定義配置類
@EnableConfigurationProperties:屬性類
@AutoConfigureAfter: 自動配置應在XXX的自動配置類之後應用。
@AutoConfigureBefore: 自動配置應在XXX的自動配置類之前應用
@AutoConfigureOrder:定義配置類執行的順序
@ConditionalOnBean:當容器裡有指定的Bean 時才生成
@ConditionalOnMissingBean:當容器裡沒有指定Bean 時才生成
@ConditionalOnClass:當類路徑下有指定的類時才生成
@ConditionalOnMissingClass:當類路徑下沒有指定的類時才生成
@ConditionalOnExpression:基於SpEL 表示式作為判斷條件。
@ConditionalOnJava:基於JVM 版本作為判斷條件。
@ConditionalOnJndi:在JNDI存在的條件下查詢指定的位置。
@ConditionalOnProperty:指定的屬性是否有指定的值。
@ConditionalOnResource:類路徑是否有指定的值。
@ConditionalOnSingleCandidate:當指定Bean 在容器中只有一個,或者雖然有多個但是指定首選的Bean。
@ConditionalOnWebApplication:當前專案是Web 專案的條件下。
@ConditionalOnNotWebApplication:當前專案不是Web 專案的條件下。
spring.factories
src/resources/META-INF/spring.factories: 配置RedisAutoConfig在此檔案,則spring boot會自動生成初始化此類
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
common.redis.spring.boot.autoconfigure.RedisAutoConfig
3.common-redis-spring-boot-starter
pom.xml
<?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">
<parent>
<artifactId>common-redis-spring-boot</artifactId>
<groupId>com.sid</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../../common-redis-spring-boot/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common-redis-spring-boot-starter</artifactId>
<dependencies>
<dependency>
<groupId>com.sid</groupId>
<artifactId>common-redis-spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>com.sid</groupId>
<artifactId>common-redis</artifactId>
</dependency>
</dependencies>
</project>
4.common-redis
common-redis包中大致程式碼
public class RedisUtil {
/**
* @Description: 這個redisTemplate 自動配置了連線池
* maxIdle = 60
* maxActive = 60
* maxWait = 3000
*
* 預設使用序列化:
* template.setKeySerializer(new StringRedisSerializer());
* template.setHashKeySerializer(new StringRedisSerializer());
* template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
* template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
* @Author: Sid
* @Date: 2018-11-08 15:16
* @since: 1.0
*/
private static RedisTemplate redisTemplate;
private static final AtomicBoolean init = new AtomicBoolean(false);
public static void init(RedisTemplate redisTemplate) {
if (init.compareAndSet(false, true)) {
RedisUtil.redisTemplate = redisTemplate;
}
}
public static<V> V get(String key) {
return (V)redisTemplate.opsForValue().get(key);
}
public static <V> void set(String key ,V value){
redisTemplate.opsForValue().set(key,value);
}
}
5.測試
新建一個專案,引入common-redis-spring-boot-starter包
然後直接使用common-redis中的RedisUtil
ModelTest modelTest = new ModelTest();
modelTest.setName("小李");
modelTest.setAge(27);
RedisUtil.set("common-redis:test:modelTest1",modelTest);
RedisUtil.set("common-redis:test:string1","測試");
RedisUtil.get("common-redis:test:string1");