自定义访问rabbitmq的框架(一)

这是由spring amqp框架简化而来的一个自定义框架,去除了很多平时用不到的东西,同时也根据自己的需要,在特定的地方做了一些修改。

核心类是下面的4个:
CacheConnectionFactory 这个工厂,缓存了连接和信道
UdConsumerContainer 消费者池
BlockingQueueConsumer 消费者
RabbitMQHelper 帮助类(提供了各种声明方法)

接下来先说CacheConnectionFactory 类:
主要作用是创建连接,以及信道池。

public Channel createChannel(CacheConnectionFactory.ChannelCachingConnectionProxy proxy)这方法用于创建信道。
创建信道之前,先检查连接是否开启或是否存在,如果没有开启,则开启连接

 synchronized(this.connectionMonitor) {
                if(!this.connection.isOpen()) {
                    this.connection.target = null;

                    try {
                        this.createConnection();
                    } catch (Exception var5) {
                        throw new RuntimeException();
                    }
                }
            }

然后使用连接创建信道,这里使用了信号量来限制一个连接可以创建的信道的数量。每次创建一个信道时,checkoutPermits会减1。
再从缓存的信道池中获取一个信道,检查信道是否可用,如果不可用,则表示信道损坏,需要重新创建。
这里将真实的信道,包装在了一个代理类ChannelProxy中。

 private Channel doCreateBareChannel(CacheConnectionFactory.ChannelCachingConnectionProxy connection) {
        ChannelProxy channelProxy = null;
        Semaphore checkoutPermits = null;
        if(this.channelCheckoutTimeout > 0L) {
            checkoutPermits = (Semaphore)this.checkoutPermits.get(connection);
            if(checkoutPermits == null) {
                throw new IllegalStateException("没有为连接设置permits的值 " + connection);
            }

            try {
                if(!checkoutPermits.tryAcquire(this.channelCheckoutTimeout, TimeUnit.MILLISECONDS)) {
                    throw new RuntimeException("没有可用的信道");
                }
            } catch (InterruptedException var10) {
                Thread.currentThread().interrupt();
                throw new RuntimeException("获取信道时发生了中断");
            }
        }

        LinkedList<ChannelProxy> channelList = this.channelProxyLinkedList;
        if(connection.isOpen()) {
            synchronized(channelList) {
                for(; !channelList.isEmpty(); channelProxy = null) {
                    channelProxy = (ChannelProxy)channelList.removeFirst();
                    if(channelProxy.isOpen()) {
                        break;
                    }

                    try {
                        Channel target = channelProxy.getTargetChannel();
                        if(target != null) {
                            target.close();
                        }
                    } catch (TimeoutException var8) {
                        ;
                    } catch (IOException var9) {
                        ;
                    }
                }

                if(channelProxy == null) {
                    try {
                        channelProxy = this.createBareChannel(connection, channelList);
                    } catch (Exception var11) {
                        if(checkoutPermits != null) {
                            checkoutPermits.release();
                        }

                        throw new RuntimeException(var11);
                    }
                }
            }
        }

        return channelProxy;
    }

创建信道时,使用了动态代理,目的是修改信道的关闭方法,在关闭信道时,把信道还回信道池。

 private final class CacheChannelInvocationHandler implements InvocationHandler {
        private final CacheConnectionFactory.ChannelCachingConnectionProxy connectionProxy;
        private final LinkedList<ChannelProxy> channelProxyLinkedList;
        private final String channelListIdentity;
        private final Object targetMonitor = new Object();
        private volatile Channel target;
        private volatile boolean txStarted;

        public CacheChannelInvocationHandler(CacheConnectionFactory.ChannelCachingConnectionProxy var1, LinkedList<ChannelProxy> connectionProxy, Channel channelProxyLinkedList) {
            this.connectionProxy = connectionProxy;
            this.channelProxyLinkedList = channelProxyLinkedList;
            this.target = channel;
            this.channelListIdentity = ObjectUtils.getIdentityHexString(channelProxyLinkedList);
        }

        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            String methodName = method.getName();
            if(methodName.equals("equals")) {
                return Boolean.valueOf(proxy == args[0]);
            } else if(methodName.equals("hashCode")) {
                return Integer.valueOf(System.identityHashCode(proxy));
            } else if(methodName.equals("toString")) {
                return "Cache Rabbit Channel: " + this.target + ",conn:" + this.connectionProxy;
            } else if(methodName.equals("close")) {
                if(CacheConnectionFactory.this.active) {
                    LinkedList var14 = this.channelProxyLinkedList;
                    synchronized(this.channelProxyLinkedList) {
                        if(this.channelProxyLinkedList.size() < CacheConnectionFactory.this.channelCacheSize || this.channelProxyLinkedList.contains(proxy)) {
                            this.releasePermit(proxy);
                            this.logicClose((ChannelProxy)proxy);
                            return null;
                        }
                    }
                }

                this.physicalClose();
                this.releasePermit(proxy);
                return null;
            } else if(methodName.equals("isOpen")) {
                return Boolean.valueOf(this.target != null && this.target.isOpen());
            } else {
                Object result;
                try {
                    if(this.target == null || !this.target.isOpen()) {
                        this.target = null;
                    }

                    Object monitor = this.targetMonitor;
                    synchronized(monitor) {
                        if(this.target == null) {
                            this.target = CacheConnectionFactory.this.createChannel(this.connectionProxy);
                        }

                        result = method.invoke(this.target, args);
                        return result;
                    }
                } catch (InvocationTargetException var13) {
                    if(this.target == null || !this.target.isOpen()) {
                        this.target = null;
                        result = this.targetMonitor;
                        Object var7 = this.targetMonitor;
                        synchronized(this.targetMonitor) {
                            if(this.target == null) {
                                this.target = CacheConnectionFactory.this.createChannel(this.connectionProxy);
                            }
                        }
                    }

                    throw var13.getTargetException();
                }
            }
        }

        private void physicalClose() {
            if(this.target != null) {
                try {
                    this.asyncClose();
                } finally {
                    this.target = null;
                }
            }

        }

        private void asyncClose() {
            CacheConnectionFactory.this.deferredCloseExecutor.execute(() -> {
                try {
                    Thread.sleep(5000L);
                } catch (InterruptedException var14) {
                    Thread.currentThread().interrupt();
                } finally {
                    try {
                        this.target.close();
                    } catch (IOException var12) {
                        ;
                    } catch (TimeoutException var13) {
                        ;
                    }

                }

            });
        }

        private void logicClose(ChannelProxy proxy) {
            if(this.target != null) {
                if(this.target != null && !this.target.isOpen()) {
                    Object var2 = this.targetMonitor;
                    synchronized(this.targetMonitor) {
                        if(this.target != null && !this.target.isOpen()) {
                            if(this.channelProxyLinkedList.contains(proxy)) {
                                this.channelProxyLinkedList.remove(proxy);
                            }

                            this.target = null;
                            return;
                        }
                    }
                }

                if(!this.channelProxyLinkedList.contains(proxy)) {
                    this.channelProxyLinkedList.addLast(proxy);
                }
            }

        }

        private void releasePermit(Object proxy) {
            if(CacheConnectionFactory.this.channelCheckoutTimeout > 0L) {
                LinkedList<ChannelProxy> channelProxies = this.channelProxyLinkedList;
                LinkedList var3 = this.channelProxyLinkedList;
                synchronized(this.channelProxyLinkedList) {
                    if(channelProxies.contains(proxy)) {
                        return;
                    }
                }

                Semaphore checkoutPermits = (Semaphore)CacheConnectionFactory.this.checkoutPermits.get(this.connectionProxy);
                if(checkoutPermits != null) {
                    checkoutPermits.release();
                }
            }

        }
    }

源码:

public class CacheConnectionFactory {
    private final ConnectionFactory rabbitConnectionFactory = new ConnectionFactory();
    private final Map<CacheConnectionFactory.ChannelCachingConnectionProxy, Semaphore> checkoutPermits;
    private final Object connectionMonitor;
    private final CacheConnectionFactory.ChannelCachingConnectionProxy connection;
    private volatile int channelCacheSize;
    private volatile long channelCheckoutTimeout;
    private final LinkedList<ChannelProxy> channelProxyLinkedList;
    private volatile boolean active = true;
    private final ExecutorService deferredCloseExecutor;

    public CacheConnectionFactory(@Value("${rabbitmq.ip}") String hostName, @Value("${rabbitmq.port}") int port, @Value("${rabbitmq.username}") String username, @Value("${rabbitmq.password}") String password, @Value("${rabbitmq.channels}") int channelCacheSize, @Value("${rabbitmq.checkTimeOut}") long channelCheckoutTimeout) {
        this.rabbitConnectionFactory.setPort(port);
        this.rabbitConnectionFactory.setHost(hostName);
        this.rabbitConnectionFactory.setUsername(username);
        this.rabbitConnectionFactory.setPassword(password);
        this.channelCacheSize = channelCacheSize;
        this.channelCheckoutTimeout = channelCheckoutTimeout;
        this.checkoutPermits = new HashMap();
        this.connectionMonitor = new Object();
        this.connection = new CacheConnectionFactory.ChannelCachingConnectionProxy((Connection)null);
        this.channelProxyLinkedList = new LinkedList();
        this.deferredCloseExecutor = Executors.newCachedThreadPool();
    }

    public final CacheConnectionFactory.ChannelCachingConnectionProxy createConnection() throws IOException, TimeoutException {
        if(this.connection.target == null) {
            Object var1 = this.connectionMonitor;
            synchronized(this.connectionMonitor) {
                if(this.connection.target == null) {
                    this.connection.target = this.rabbitConnectionFactory.newConnection();
                    if(!this.checkoutPermits.containsKey(this.connection)) {
                        this.checkoutPermits.put(this.connection, new Semaphore(this.channelCacheSize));
                    }

                    this.connection.closeNotified.set(false);
                }
            }
        }

        return this.connection;
    }

    public Channel createChannel(CacheConnectionFactory.ChannelCachingConnectionProxy proxy) {
        if(!this.connection.isOpen()) {
            Object var2 = this.connectionMonitor;
            synchronized(this.connectionMonitor) {
                if(!this.connection.isOpen()) {
                    this.connection.target = null;

                    try {
                        this.createConnection();
                    } catch (Exception var5) {
                        throw new RuntimeException();
                    }
                }
            }
        }

        return this.doCreateBareChannel(this.connection);
    }

    private Channel doCreateBareChannel(CacheConnectionFactory.ChannelCachingConnectionProxy connection) {
        ChannelProxy channelProxy = null;
        Semaphore checkoutPermits = null;
        if(this.channelCheckoutTimeout > 0L) {
            checkoutPermits = (Semaphore)this.checkoutPermits.get(connection);
            if(checkoutPermits == null) {
                throw new IllegalStateException("没有为连接设置permits的值 " + connection);
            }

            try {
                if(!checkoutPermits.tryAcquire(this.channelCheckoutTimeout, TimeUnit.MILLISECONDS)) {
                    throw new RuntimeException("没有可用的信道");
                }
            } catch (InterruptedException var10) {
                Thread.currentThread().interrupt();
                throw new RuntimeException("获取信道时发生了中断");
            }
        }

        LinkedList<ChannelProxy> channelList = this.channelProxyLinkedList;
        if(connection.isOpen()) {
            synchronized(channelList) {
                for(; !channelList.isEmpty(); channelProxy = null) {
                    channelProxy = (ChannelProxy)channelList.removeFirst();
                    if(channelProxy.isOpen()) {
                        break;
                    }

                    try {
                        Channel target = channelProxy.getTargetChannel();
                        if(target != null) {
                            target.close();
                        }
                    } catch (TimeoutException var8) {
                        ;
                    } catch (IOException var9) {
                        ;
                    }
                }

                if(channelProxy == null) {
                    try {
                        channelProxy = this.createBareChannel(connection, channelList);
                    } catch (Exception var11) {
                        if(checkoutPermits != null) {
                            checkoutPermits.release();
                        }

                        throw new RuntimeException(var11);
                    }
                }
            }
        }

        return channelProxy;
    }

    private ChannelProxy createBareChannel(CacheConnectionFactory.ChannelCachingConnectionProxy connection, LinkedList<ChannelProxy> channelList) throws IOException {
        Channel channel = connection.createChannel();
        Class[] interfaces = new Class[]{ChannelProxy.class};
        return (ChannelProxy)Proxy.newProxyInstance(ChannelProxy.class.getClassLoader(), interfaces, new CacheConnectionFactory.CacheChannelInvocationHandler(this.connection, channelList, channel));
    }

    final class ChannelCachingConnectionProxy implements Closeable {
        Connection target;
        final AtomicBoolean closeNotified = new AtomicBoolean(false);

        public ChannelCachingConnectionProxy(Connection connection) {
            this.target = connection;
        }

        public void close() {
            try {
                this.target.close();
            } catch (IOException var2) {
                throw new RuntimeException("ChannelCachingConnectionProxy:close失败");
            }
        }

        public Channel createChannel() throws IOException {
            return this.target.createChannel();
        }

        public boolean isOpen() {
            return this.target != null && this.target.isOpen();
        }
    }

    private final class CacheChannelInvocationHandler implements InvocationHandler {
        private final CacheConnectionFactory.ChannelCachingConnectionProxy connectionProxy;
        private final LinkedList<ChannelProxy> channelProxyLinkedList;
        private final String channelListIdentity;
        private final Object targetMonitor = new Object();
        private volatile Channel target;
        private volatile boolean txStarted;

        public CacheChannelInvocationHandler(CacheConnectionFactory.ChannelCachingConnectionProxy var1, LinkedList<ChannelProxy> connectionProxy, Channel channelProxyLinkedList) {
            this.connectionProxy = connectionProxy;
            this.channelProxyLinkedList = channelProxyLinkedList;
            this.target = channel;
            this.channelListIdentity = ObjectUtils.getIdentityHexString(channelProxyLinkedList);
        }

        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            String methodName = method.getName();
            if(methodName.equals("equals")) {
                return Boolean.valueOf(proxy == args[0]);
            } else if(methodName.equals("hashCode")) {
                return Integer.valueOf(System.identityHashCode(proxy));
            } else if(methodName.equals("toString")) {
                return "Cache Rabbit Channel: " + this.target + ",conn:" + this.connectionProxy;
            } else if(methodName.equals("close")) {
                if(CacheConnectionFactory.this.active) {
                    LinkedList var14 = this.channelProxyLinkedList;
                    synchronized(this.channelProxyLinkedList) {
                        if(this.channelProxyLinkedList.size() < CacheConnectionFactory.this.channelCacheSize || this.channelProxyLinkedList.contains(proxy)) {
                            this.releasePermit(proxy);
                            this.logicClose((ChannelProxy)proxy);
                            return null;
                        }
                    }
                }

                this.physicalClose();
                this.releasePermit(proxy);
                return null;
            } else if(methodName.equals("isOpen")) {
                return Boolean.valueOf(this.target != null && this.target.isOpen());
            } else {
                Object result;
                try {
                    if(this.target == null || !this.target.isOpen()) {
                        this.target = null;
                    }

                    Object monitor = this.targetMonitor;
                    synchronized(monitor) {
                        if(this.target == null) {
                            this.target = CacheConnectionFactory.this.createChannel(this.connectionProxy);
                        }

                        result = method.invoke(this.target, args);
                        return result;
                    }
                } catch (InvocationTargetException var13) {
                    if(this.target == null || !this.target.isOpen()) {
                        this.target = null;
                        result = this.targetMonitor;
                        Object var7 = this.targetMonitor;
                        synchronized(this.targetMonitor) {
                            if(this.target == null) {
                                this.target = CacheConnectionFactory.this.createChannel(this.connectionProxy);
                            }
                        }
                    }

                    throw var13.getTargetException();
                }
            }
        }

        private void physicalClose() {
            if(this.target != null) {
                try {
                    this.asyncClose();
                } finally {
                    this.target = null;
                }
            }

        }

        private void asyncClose() {
            CacheConnectionFactory.this.deferredCloseExecutor.execute(() -> {
                try {
                    Thread.sleep(5000L);
                } catch (InterruptedException var14) {
                    Thread.currentThread().interrupt();
                } finally {
                    try {
                        this.target.close();
                    } catch (IOException var12) {
                        ;
                    } catch (TimeoutException var13) {
                        ;
                    }

                }

            });
        }

        private void logicClose(ChannelProxy proxy) {
            if(this.target != null) {
                if(this.target != null && !this.target.isOpen()) {
                    Object var2 = this.targetMonitor;
                    synchronized(this.targetMonitor) {
                        if(this.target != null && !this.target.isOpen()) {
                            if(this.channelProxyLinkedList.contains(proxy)) {
                                this.channelProxyLinkedList.remove(proxy);
                            }

                            this.target = null;
                            return;
                        }
                    }
                }

                if(!this.channelProxyLinkedList.contains(proxy)) {
                    this.channelProxyLinkedList.addLast(proxy);
                }
            }

        }

        private void releasePermit(Object proxy) {
            if(CacheConnectionFactory.this.channelCheckoutTimeout > 0L) {
                LinkedList<ChannelProxy> channelProxies = this.channelProxyLinkedList;
                LinkedList var3 = this.channelProxyLinkedList;
                synchronized(this.channelProxyLinkedList) {
                    if(channelProxies.contains(proxy)) {
                        return;
                    }
                }

                Semaphore checkoutPermits = (Semaphore)CacheConnectionFactory.this.checkoutPermits.get(this.connectionProxy);
                if(checkoutPermits != null) {
                    checkoutPermits.release();
                }
            }

        }
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值