Redis的Java继承

问题描述

具有订阅者类别:

import org.apache.log4j.LogManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.*;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Properties;


public class Subscriber extends JedisPubSub {
    private static final org.apache.log4j.Logger logger = LogManager.getLogger(Subscriber.class);


    @Override
    public void onMessage(String channel,String message) {
        logger.info("Message received. Channel: " + channel + ",Msg: " + message);

    }


    @Override
    public void onSubscribe(String channel,int subscribedChannels) {
        logger.info("Subscribed to channel: " + channel);
    }


    public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    JedisSentinelPool pool = new JedisSentinelPool(masterName,sentinelsHashSet,password);
                    Jedis jPublisher = pool.getResource();
                    Jedis jedis = pool.getResource();
                    Subscriber subscriber = new Subscriber();
                    jedis.subscribe(subscriber,channel);
                    jedis.quit();
                } catch (Exception e) {
                    logger.error(e.toString());
                }
            }
        });
        t.run();
    }
}

我基本上想打印在Redis通道上收到的所有消息,我想用不同的onMessage或onSubscribe方法创建子类。我从Main class调用订户类

Subscriber sb = new Subscriber();
sb.main(new String[]{});

所以我尝试了:

  1. 复制main方法并将Subscriber subscriber = new Subscriber();更改为SubscriberExtended subscriber = new SubscriberExtended();并通过以下方式从Main类进行调用: 1.1)
Subscriber sb = new SubscriberExtended();
sb.main(new String[]{});

SubscriberExtended sb = new SubscriberExtended();
sb.main(new String[]{});
    import org.apache.log4j.LogManager;
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisSentinelPool;

    import java.util.Arrays;
    import java.util.HashSet;
    import java.util.Properties;

    public class SubscriberExtended extends Subscriber {
        private static final org.apache.log4j.Logger logger = LogManager.getLogger(SubscriberExtended.class);

        @Override
        public void onSubscribe(String channel,int subscribedChannels) {
            logger.info("Subscribed to channel from Extended class: " + channel);
        }

        public SubscriberExtended() {

        }
            public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    JedisSentinelPool pool = new JedisSentinelPool(masterName,password);
                    Jedis jPublisher = pool.getResource();
                    Jedis jedis = pool.getResource();
                    SubscriberExtended subscriber = new SubscriberExtended();
                    jedis.subscribe(subscriber,channel);
                    jedis.quit();
                } catch (Exception e) {
                    logger.error(e.toString());
                }
            }
        });
        t.run();

    }
  1. 我也尝试过使用构造函数
public SubscriberExtended() {
    super.main(new String[]{});
}

其他配置几乎没有任何效果。 我要实现的目标是创建SubscriberExtended类,该类的行为与Subscriber类相同,但重写onMessage或onSubscribe方法。谁能帮我吗?

解决方法

这似乎应该起作用,尽管我不确定为什么要向所有类添加静态主体。 您应该能够执行以下操作:

public class Subscriber extends JedisPubSub {
    private static final org.apache.log4j.Logger logger = LogManager.getLogger(Subscriber.class);

    @Override
    public void onMessage(String channel,String message) {
        logger.info("Message received. Channel: "+channel+",Msg: "+message);
    }

    @Override
    public void onSubscribe(String channel,int subscribedChannels) {
        logger.info("Subscribed to channel: " + channel);
    }

    public void start() {
        Thread t = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    JedisSentinelPool pool = new JedisSentinelPool(masterName,sentinelsHashSet,password);
                    Jedis jedis = pool.getResource();
                    jedis.subscribe(this,channel);
                    jedis.quit();
                } catch (Exception e) {
                    logger.error(e.toString());
                }
            }
        });
        t.start();
    }
}

public class SubscriberExtended extends Subscriber {
    @Override
    public void onMessage(String channel,String message) {
        logger.info("Extended Message received. Channel: "+channel+",Msg: "+message);
    }
}

然后,从主要功能的某个地方,您将获得以下内容:

public class Main()
{
    public static void main(String[] args)
    {
        SubscriberExtended se = new SubscriberExtended();
        se.start();

        while(true) {
             // do something else or sleep
        }
    }
}

我相信您犯的一个错误是调用t.run()而不是t.start()。 t.run()将不会返回,除非订阅由于某种原因而失败,例如与REDIS的连接已关闭。 t.start()将启动线程。

您似乎也无缘无故地从jedis池中获取发布者连接。

另一个问题在这里:

Subscriber sb = new SubscriberExtended();
sb.main(new String[]{});

sb.main还将继续调用new SubscriberExtended()与订阅一起使用,因此您的sb对象将不会收到任何发布-它们将转到在sb.main中创建的实例代替。在start()方法中使用“ this”进行订阅将解决该问题。

设置完成后,您可以继续使用redis-cli连接到REDIS,然后发布以查看您的程序是否收到该消息。