Jedis是Redis的Java实现客户端,提供了比较全面的Redis操作方法,且与Redis的命令很接近。这是在spring boot框架下的,对jedis封装成工具,方便调用。
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
1、单机模式封装
单机模式下使用jedis的例子是这样的:
JedisPool pool = JedisFactory.createJedisPool(new RedisProperties());
Jedis jedis = pool.getResource();
try {
jedis = pool.getResource();
return method.invoke(jedis, args);
} finally {
if (jedis != null) {
jedis.close();
}
}
但这样就会有try catch finally的结构来关闭jedis,如果每次调用都需要这样写就会有很多重复代码,可以用代理模式来优化。创建JedisHandler实现InvocationHandler。
public class JedisHandler implements InvocationHandler {
private JedisPool pool;
public JedisHandler(JedisPool pool) {
this.pool = pool;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Jedis jedis = null;
try {
System.out.println("进入代理");
jedis = pool.getResource();
return method.invoke(jedis, args);
} finally {
if (jedis != null) {
jedis.close();
}
}
}
}
然后创建一个工厂类,用来创建jedis的实例。RedisProperties是pring-boot-autoconfigure的配置类,对应yml配置的spring.redis的配置。Jedis类实现JedisCommands接口,所以调用createJedis方法最后返回的是代理类,而不用重复写try这些重复代码,每次调用JedisCommands的方法,代理类都会自动关闭jedis。
public class JedisFactory {
/**
* 创建单机连接池
*
* @param properties
* @return
*/
public static JedisPool createJedisPool(RedisProperties properties) {
JedisPoolConfig config = setConfig(properties);
return new JedisPool(config, properties.getHost(), properties.getPort(), 3000,
properties.getPassword(), properties.getDatabase());
}
/**
* 创建单机客户端
*
* @param properties
* @return
*/
public static JedisCommands createJedis(RedisProperties properties) {
JedisPoolConfig config = setConfig(properties);
JedisPool jedisPool = new JedisPool(config, properties.getHost(), properties.getPort(), 3000,
properties.getPassword(), properties.getDatabase());
return createJedis(jedisPool);
}
/**
* 创建单机客户端
*
* @param pool
* @return
*/
public static JedisCommands createJedis(JedisPool pool) {
JedisHandler handler = new JedisHandler(pool);
return (JedisCommands) Proxy.newProxyInstance(JedisCommands.class.getClassLoader(), new Class[]{JedisCommands.class}, handler);
}
/**
* 创建集群客户端
*
* @param properties
* @return
*/
public static JedisCluster createCluster(RedisProperties properties) {
List<String> nodeStr = properties.getCluster().getNodes();
Set<HostAndPort> nodes = new HashSet<>();
for (String node : nodeStr) {
String[] hostPort = node.split(":");
nodes.add(new HostAndPort(hostPort[0], Integer.valueOf(hostPort[1])));
}
JedisPoolConfig config = setConfig(properties);
// 利用上面的集群节点nodes和poolConfig,创建redis集群连接池,并获取一个redis连接
return new JedisCluster(nodes, 3000, 3000, 5, properties.getPassword(), config);
}
/**
* 获取配置
*
* @param properties
* @return
*/
private static JedisPoolConfig setConfig(RedisProperties properties) {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(properties.getJedis().getPool().getMaxIdle());
config.setMaxIdle(properties.getJedis().getPool().getMaxIdle());
config.setMinIdle(properties.getJedis().getPool().getMinIdle());
config.setMaxWaitMillis(3000);
config.setTestOnBorrow(false);
config.setTestOnReturn(false);
return config;
}
}
使用时创建JedisCommands的bean,然后用@Autowired注解调用即可。
@Configuration
@EnableConfigurationProperties(RedisProperties.class)
public class JedisConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(JedisAutoConfiguration.class);
private JedisPool pool;
@Bean
public JedisCommands jedisCommands(RedisProperties properties) {
//单机模式
LOGGER.info("redis connect {}", properties.getHost());
pool = JedisFactory.createJedisPool(properties);
JedisCommands commands = JedisFactory.createJedis(pool);
return commands;
}
@PreDestroy
public void destroy() {
if (pool != null) {
LOGGER.info("close redis pool");
pool.close();
}
}
}
上面的使用例子需要手动创建bean,但可以更进一步,使用spring boot 的自动注入,把jedis封装成依赖包,当其他应用使用时,只需依赖此依赖包,并在配置文件yml配置连接等,就可直接调用了。
@Configuration
@ConditionalOnClass({Jedis.class, JedisCluster.class})
@EnableConfigurationProperties(RedisProperties.class)
public class JedisAutoConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(JedisAutoConfiguration.class);
private JedisPool pool;
@Bean
@ConditionalOnMissingBean
public JedisCommands jedisCommands(RedisProperties properties) {
//单机模式
LOGGER.info("redis connect {}", properties.getHost());
pool = JedisFactory.createJedisPool(properties);
JedisCommands commands = JedisFactory.createJedis(pool);
return commands;
}
@PreDestroy
public void destroy() {
if (pool != null) {
LOGGER.info("close redis pool");
pool.close();
}
}
}
自定义启动使用jedis的注解@EnableJedis
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({JedisAutoConfiguration.class})
public @interface EnableJedis {
}
使用时只需在@SpringCloudApplication 注解的启动类上加入@EnableJedis就默认使用jedis,然后在需要调用时用@Autowired注解调用即可。
网友评论