Jedis利用lombok和try with resource等多种归还连接、关闭资源方法

起源

先写一个测试,探究出错起源:

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootApplicationTests {

    @Autowired
    JedisPool jedisPool;

    @Test
    public void test() {
        try {
            for (int i = 1; i <= 50; i++) {
                Jedis jedis = jedisPool.getResource();
                System.out.println(i);
                // doSomething
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

毫无疑问,无限制的取资源而不关闭是会出错的,我这里设置了 maxTotal 为 30 ,所以到了 30 个连接后就不能取了。

下面用几种方法解决这个问题。

Lombok 法

lombok 里的 @Cleanup 注解是可以帮我们关闭资源的,只要在获取资源行开头加注解即可:

for (int i = 1; i <= 50; i++) {
    @Cleanup Jedis jedis = jedisPool.getResource();
    System.out.println(i);
    // doSomething
}

try with resource 法

这个方法应该属于广为人知的方法了,利用 try 隐含的 finally 里会自动关闭资源方法:

try (Jedis jedis = pool.getResource()) {
    // do something
}

工具类法

我们直接在工具类就把关闭写好也可以,这里示例一个方法:

public static void redisPut(String key, String val) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.set(key, val);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            jedis.close();
        }
    }

但是这种工具类会特别长,不够简洁,而且 idea 会提示你转换成 try with resource 方法的。

包装法

可以选择不暴露 Jedis 本身,改为包装的工具接口:

public interface CallWithJedis {
    // 接口提供方法,由实现类来实现具体的业务逻辑
    void call(Jedis jedis);

    class RedisPool {
        private JedisPool pool;

        // 加载类的时候初始化连接池
        public RedisPool() {
            // 这里采用默认配置,也可以自定义配置
            this.pool = new JedisPool();
        }

        public void execute(CallWithJedis caller) {
            // 业务调用此方法,已经将获取的连接使用try with resource 写法包装。
            try (Jedis jedis = pool.getResource()) {
                caller.call(jedis);
            }
        }
    }
}

之后我们使用包装的方法即可:

public static void main(String[] args) {
    CallWithJedis.RedisPool redis = new CallWithJedis.RedisPool();
    redis.execute(new CallWithJedis() {
        @Override
        public void call(Jedis jedis) {
        // do something with jedis
        }
    });
}

这种方法本质还是 try with resource。

结果

只要归还了连接,那最初写的测试方法就可以顺利执行:
Jedis利用lombok和try with resource等多种归还连接、关闭资源方法_第1张图片

你可能感兴趣的:(Java)