JAVAのredisクライアントの実装について

11752 ワード

最近javaのredis使用,特にspringでの使用について検討し,まとめた.
まずjavaのredisクライアントが使いやすく、Jedisもよく使われています.Jedisについて注意すべき点は2つあります.1.Jedisはスレッドが安全ではありません.つまり、複数のスレッドがJedisの同じインスタンスを同時に使用している場合に、同時発生する問題が発生します.だからJedisはスレッドプールJedisPoolを提供して、これは私たちが後のコードでも使用します.2.JedisPoolでは、手動でJedisオブジェクトを解放し、returnResourceメソッドまたはreturnBrokenResourceメソッドを呼び出す必要があります.
また、私たちの例では、jedisを呼び出すたびにjedisオブジェクトを解放する方法を書きたくないので、cglibを利用してAOPを作成し、すべてのjedisメソッドをキャプチャし、オブジェクトを解放する接尾辞を付けました.
前提は基本的に終わりますが、コードを直接見てみましょう.コードには主に2つのクラスがあり、EnhanceRedisとRedisCacheSupportがあります.このうちEnhanceRedisはJedisの初期化を担当し、AOP部分RedisCacheSupportはsetValue、getkeyなどの具体的な業務の実現を担当しています.
//Component  ,           
//              ,  FactoryBean       bean,         (@autowired)EnhancerRedis   
//MethodInterceptor cglib     ,        ,    jedis  ,  AOP
//JedisCommands,MultiKeyCommands, AdvancedJedisCommands  xxxxCommands  Jedis   ,       redis   
@Component
public class EnhancerRedis implements FactoryBean,  MethodInterceptor, JedisCommands,
    MultiKeyCommands, AdvancedJedisCommands, ScriptingCommands,
    BasicCommands, ClusterCommands{

    //        value  , properties       redis     ,  host,      
    @Value("${redis.maxTotal}")
    private int maxTotal;
    @Value("${redis.maxWaitMillis}")
    private int maxWaitMillis;
    @Value("${redis.maxIdle}")
    private int maxIdle;
    @Value("${redis.minIdle}")
    private int minIdle;
    @Value("${redis.timeBetweenEvictionRunsMillis}")
    private int timeBetweenEvictionRunsMillis;
    @Value("${redis.hostName}")
    private String host;
    @Value("${redis.port}")
    private int port;
    @Value("${redis.password}")
    private String password;

    //Jedis    
    private JedisPool pool = null;

    //PostConstruct    , @PostConstruct            Servle     ,            。PostConstruct         ,servlet init()      。
    @PostConstruct
    public void init() {
        // JedisPool       
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(maxTotal);
        config.setMaxWaitMillis(maxWaitMillis);
        config.setMaxIdle(maxIdle);
        config.setMinIdle(minIdle);
        config.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        if(password == null || password.trim().equals("")) {
            pool = new JedisPool(config, host, port);
        } else {
            pool = new JedisPool(config, host, port, Protocol.DEFAULT_TIMEOUT, password);
        }
    }


    //       FactoryBean  ,         beanfactory      
    @Override
    public EnhancerRedis getObject() throws Exception {
        //Enhancer   cglib,        (create  ),       (setSuperclass),       (setCallback)。           EnhancerRedis  。
        Enhancer enhancer = new  Enhancer();
        enhancer.setSuperclass(EnhancerRedis.class);
        enhancer.setCallback(this);
        return (EnhancerRedis) enhancer.create();
    }

   //       FactoryBean  ,        bean    EnhancerRedis
    @Override
    public Class getObjectType() {
        return EnhancerRedis.class;
    }

    //       FactoryBean  ,     bean     
    @Override
    public boolean isSingleton() {
        return true;
    }

    //       MethodInterceptor,      EnhancerRedis    
    //     getObject()       ,         EnhancerRedis   。       EnhancerRedis          ,    intercept     
    //           :1. EnhancerRedis        ,   JedisPool          ,  EnhancerRedis     Jedis   ,  EnhancerRedis      JedisPool  jedis       。              JedisPool        ,           
    //2.         returnRedis     JedisPool   jedis  ,              ,                ,           
    //       ,        Jedis       jedis   ,       Jedis      
    @Override
    public Object intercept(Object obj, Method method, Object[] args,
            MethodProxy proxy) throws Throwable {
        Jedis redis = getRedis();
        Object result = null;
        try {
            //        (          )
            Method methodRedis = redis.getClass().getMethod(method.getName(), method.getParameterTypes());
            //     , JedisPool             (Jedis redis = getRedis())
            result = methodRedis.invoke(redis, args);
            //     ,  JedisPool   
            returnRedis(redis);
        } catch (Exception e) {
            //      ,    JedisPool   
            returnBrokenRedis(redis);
        }
        return result;
    }



    // Jedis          
    public Jedis getRedis() {
        return pool.getResource();
    }

    //           
    public void returnRedis(Jedis jed){
        pool.returnResource(jed);
    }

    //           
    public void returnBrokenRedis(Jedis jed){
        pool.returnBrokenResource(jed);
    }


    //redis     ,      ,     jedis      
    //        ,    XXXCommands  ,  redis     
    //               ,                     ,    intercept   ,    JedisPool  jedis     , jedis          ,   return null,                
    @Override
    public String clusterNodes() {
        // TODO Auto-generated method stub
        return null;
    }


    @Override
    public String clusterMeet(String ip, int port) {
        // TODO Auto-generated method stub
        return null;
    }

EnhancerRedisクラスは、主にjedisの初期化とパッケージです.次にredisの実際の操作クラスRedisCacheSupportについて説明します.
public class RedisCacheSupport {
    final static Logger LOGGER = LoggerFactory.getLogger(RedisCacheSupport.class);
    protected static final String DEFAULT_CHARSET = "utf-8";

    //  EnhancerRedis        FactoryBean,        Autowired      。         bean   ,        EnhancerRedis getObject()  ,         Autowired    ,  EnhancerRedis redis               ,   redis          proxy
    @Autowired
    protected EnhancerRedis redis;

    //       ,  redis   key   ,        
    /*     KEY   */
    private static final String KEY_COMM = "comm_";
    /*          */
    private static final String KEY_TEAM = "team_";


    //       redis      (String    )
    //          key         ,  key=KEY_COMM + "001"
    /**
     *   key      ,    true,    false
     * @param key
     * @return
     */
    public boolean exists(String key) {
        return redis.exists(key);
    }

    /**
     *   Key       
     * @param key
     * @return
     */
    public String get(String key) {
        return redis.get(key);
    }

    /**
     *        
     * @param key       
     * @param value     
     */
    public void put(String key, String value) {
        redis.set(key, value);
    }

    /**

EnhancerRedisクラスのコードはここを見ることができます.http://download.csdn.net/download/l00149133/10158682 RedisCacheSupportクラスは非常に簡単で、コードは与えられません.