Java内部类学习(四)—— 接口中的静态内部类

今天在阅读JetServer源码protocal部分的时候碰见了内部类的又一写法。定义一个接口LoginProtocol,包括了一个域和一个方法,然后在其中写了三个内部类,分别实现了该接口,代码如下:

package org.menacheri.jetserver.handlers.netty;

import static org.menacheri.jetserver.event.Events.LOG_IN;
import static org.menacheri.jetserver.event.Events.PROTCOL_VERSION;
import static org.menacheri.jetserver.event.Events.RECONNECT;

import java.util.List;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.ChannelHandler;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder;
import org.jboss.netty.handler.codec.frame.LengthFieldPrepender;
import org.jboss.netty.handler.codec.http.HttpChunkAggregator;
import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
import org.jboss.netty.handler.codec.http.HttpResponseEncoder;
import org.jboss.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import org.menacheri.jetserver.event.Events;

/**
 * Applies a protocol to the incoming pipeline which will handle login.
 * Subsequent protocol may also be manipulated by these login handlers.
 *
 * @author Abraham Menacherry
 *
 */
public interface LoginProtocol
{
    String LOGIN_HANDLER_NAME = "loginHandler";
    /**
     * Apply a protocol on the pipeline to handle login. Implementations will
     * first "search" if the incoming bytes correspond to the implementations
     * protocol, only if they match, the correspoinding protocol will be
     * applied.
     *
     * @param buffer
     *            The incoming buffer, by default around 5 bytes will be read
     *            and passed on to detect the protocol
     * @param pipeline
     *            The channelpipeline on which the login protocol handlers need
     *            to be set.
     * @return Returs true if the protocol was applied, else false.
     */
    public boolean applyProtocol(ChannelBuffer buffer, ChannelPipeline pipeline);

    /**
     * Searches the incoming bytes of a client connection to determine if its an
     * HTTP connection, in which case Websocket or HTTP related handlers will be
     * applied on the piepline.
     *
     * @author Abraham Menacherry
     *
     */
    public static class HTTPProtocol implements LoginProtocol
    {
        private WebSocketLoginHandler webSocketLoginHandler;
        @Override
        public boolean applyProtocol(ChannelBuffer buffer,
                ChannelPipeline pipeline)
        {
            boolean isThisProtocol = false;
            final int magic1 = buffer.getUnsignedByte(buffer.readerIndex());
            final int magic2 = buffer.getUnsignedByte(buffer.readerIndex() + 1);
            if (isHttp(magic1, magic2))
            {
                pipeline.addLast("decoder", new HttpRequestDecoder());
                pipeline.addLast("aggregator", new HttpChunkAggregator(65536));
                pipeline.addLast("encoder", new HttpResponseEncoder());
                pipeline.addLast("handler", new WebSocketServerProtocolHandler("/jetsocket"));
                pipeline.addLast(LOGIN_HANDLER_NAME, webSocketLoginHandler);
                isThisProtocol = true;
            }
            return isThisProtocol;
        }

        /**
         * Method which checks if the first 2 incoming parameters are G, E or
         * similar combiantions which signal that its an HTTP protocol, since
         * some protocols like jetserver‘s default protocol send the length
         * first (which is 2 arbitrary bytes), its better if this protocol is
         * searched last to avoid switching to HTTP protocol prematurely.
         *
         * @param magic1
         * @param magic2
         * @return true if the two incoming bytes match any of the first two
         *         letter of HTTP headers like GET, POST etc.
         */
        protected boolean isHttp(int magic1, int magic2)
        {
            return magic1 == ‘G‘ && magic2 == ‘E‘ || // GET
                    magic1 == ‘P‘ && magic2 == ‘O‘ || // POST
                    magic1 == ‘P‘ && magic2 == ‘U‘ || // PUT
                    magic1 == ‘H‘ && magic2 == ‘E‘ || // HEAD
                    magic1 == ‘O‘ && magic2 == ‘P‘ || // OPTIONS
                    magic1 == ‘P‘ && magic2 == ‘A‘ || // PATCH
                    magic1 == ‘D‘ && magic2 == ‘E‘ || // DELETE
                    magic1 == ‘T‘ && magic2 == ‘R‘ || // TRACE
                    magic1 == ‘C‘ && magic2 == ‘O‘; // CONNECT
        }

        public WebSocketLoginHandler getWebSocketLoginHandler()
        {
            return webSocketLoginHandler;
        }

        public void setWebSocketLoginHandler(WebSocketLoginHandler webSocketLoginHandler)
        {
            this.webSocketLoginHandler = webSocketLoginHandler;
        }
    }

    /**
     * This is the default protocol of jetserver. If incoming event is of type
     * LOG_IN and also has appropriate protocol version as defined in the
     * {@link Events} class, then this protocol will be applied. The 3rd and 4th
     * bytes of the incoming transmission are searched to get this information.
     *
     * @author Abraham Menacherry
     *
     */
    public static class DefaultJetProtocol implements LoginProtocol
    {

        private int frameSize = 1024;
        private EventDecoder eventDecoder;
        private LoginHandler loginHandler;
        private LengthFieldPrepender lengthFieldPrepender;

        @Override
        public boolean applyProtocol(ChannelBuffer buffer,
                ChannelPipeline pipeline)
        {
            boolean isThisProtocol = false;
            final int opcode = buffer.getUnsignedByte(buffer.readerIndex() + 2);
            final int protocolVersion = buffer.getUnsignedByte(buffer
                    .readerIndex() + 3);
            if (isJetProtocol(opcode, protocolVersion))
            {
                pipeline.addLast("framer", createLengthBasedFrameDecoder());
                pipeline.addLast("eventDecoder", eventDecoder);
                pipeline.addLast(LOGIN_HANDLER_NAME, loginHandler);
                pipeline.addLast("lengthFieldPrepender", lengthFieldPrepender);
                isThisProtocol = true;
            }
            return isThisProtocol;
        }

        protected boolean isJetProtocol(int magic1, int magic2)
        {
            return ((magic1 == LOG_IN || magic1 == RECONNECT) && magic2 == PROTCOL_VERSION);
        }

        public ChannelHandler createLengthBasedFrameDecoder()
        {
            return new LengthFieldBasedFrameDecoder(frameSize, 0, 2, 0, 2);
        }

        public int getFrameSize()
        {
            return frameSize;
        }

        public void setFrameSize(int frameSize)
        {
            this.frameSize = frameSize;
        }

        public EventDecoder getEventDecoder()
        {
            return eventDecoder;
        }

        public void setEventDecoder(EventDecoder eventDecoder)
        {
            this.eventDecoder = eventDecoder;
        }

        public LoginHandler getLoginHandler()
        {
            return loginHandler;
        }

        public void setLoginHandler(LoginHandler loginHandler)
        {
            this.loginHandler = loginHandler;
        }

        public LengthFieldPrepender getLengthFieldPrepender()
        {
            return lengthFieldPrepender;
        }

        public void setLengthFieldPrepender(
                LengthFieldPrepender lengthFieldPrepender)
        {
            this.lengthFieldPrepender = lengthFieldPrepender;
        }
    }

    public static class CompositeProtocol implements LoginProtocol
    {
        private List<LoginProtocol> protocols;

        @Override
        public boolean applyProtocol(ChannelBuffer buffer,
                ChannelPipeline pipeline)
        {
            if (null != protocols)
            {
                for (LoginProtocol protocol : protocols)
                {
                    if (protocol.applyProtocol(buffer, pipeline))
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        public List<LoginProtocol> getProtocols()
        {
            return protocols;
        }

        public void setProtocols(List<LoginProtocol> protocols)
        {
            this.protocols = protocols;
        }
    }
}

在用Spring框架进行注入的时候,引用的方法是:接口所在的包名.接口名.内部类名字:

<!-- Login Protocols these decide what handlers are in the pipeline during
        login of a client to jetserver -->
    <bean id="httpLoginProtocol" class="org.menacheri.jetserver.handlers.netty.LoginProtocol.HTTPProtocol" >
        <property name="webSocketLoginHandler" ref="webSocketLoginHandler" ></property>
    </bean>

    <bean id="defaultJetLoginProtocol" class="org.menacheri.jetserver.handlers.netty.LoginProtocol.DefaultJetProtocol" >
        <property name="eventDecoder" ref="eventDecoder"></property>
        <property name="loginHandler" ref="loginHandler"></property>
        <property name="lengthFieldPrepender" ref="lengthFieldPrepender"></property>
    </bean>

    <bean id="compositeLoginProtocol" class="org.menacheri.jetserver.handlers.netty.LoginProtocol.CompositeProtocol" scope="prototype">
        <property name="protocols">
            <list>
                <ref bean="defaultJetLoginProtocol"/>
                <ref bean="httpLoginProtocol"/>
            </list>
        </property>
    </bean>
时间: 2024-10-15 22:41:56

Java内部类学习(四)—— 接口中的静态内部类的相关文章

java基础学习总结——接口

java基础学习总结——接口 一.接口的概念 JAVA是只支持单继承的,但现实之中存在多重继承这种现象,如“金丝猴是一种动物”,金丝猴从动物这个类继承,同时“金丝猴是一种值钱的东西”,金丝猴从“值钱的东西”这个类继承,同时“金丝猴是一种应该受到保护的东西”,金丝猴从“应该受到保护的东西”这个类继承.这样金丝猴可以同时从 “动物类”.“值钱的东西类”.“应该受到保护的东西” 这三个类继承,但由于JAVA只支持单继承,因此金丝猴只能从这三个类中的一个来继承,不能同时继承这三个类.因此为了封装现实生活

Java数据结构学习—Iterator接口

迭代器是一个对象,它能是我们迭代集合中的所以元素 在Java集合类API中,Iterator接口很小,只包含三个方法: 1.boolean hasNext() 如果在这次迭代中还有迭代浏览的的项,则返回true. 2.AnyType next() 返回这个迭代器还未看到的对下一个对象的引用,对象变为可见,则迭代器后移. 3.void remove() 三次浏览的最后一个项,在对next的调用之前,只能用一次这种方法. 每个集合都定义了自己的Iterator接口的实现,对java.util包中的

Java内部类学习笔记

这是我学习Java内部类的笔记 1.为什么使用内部类?使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响1.1.使用内部类最大的优点就在于它能够非常好的解决多重继承的问题,使用内部类还能够为我们带来如下特性:(1).内部类可以用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独.(2).在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类.(3).创建内部类对象的时

Java内部类学习总结

目录 目录 概述 非静态内部类 从外部类的非静态方法中实例化内部类 从外部类的静态方法中实例化内部类 内部类的this引用 静态内部类 从外部类的非静态方法中实例化静态内部类 从外部类静态方法中实例化静态内部类 匿名内部类 方法内部类 概述 最近学习python,发现python是支持多继承的,这让我想起Java是通过内部类实现的这套机制.这篇文章不是讲如何通过内部类实现多继承,而是总结一下内部类的类型和使用方法. Java内部类分为: 非静态内部类 静态内部类 局部内部类 匿名内部类 内部类在

Java内部类小程序(成员内部类,静态内部类,匿名内部类)

1 /** 2 * 测试java内部类(成员内部类,静态内部类,匿名内部类) 3 * 局部内部类不常用,就不写了. 4 * @package :java05 5 * @author shaobn 6 * @Describe : 7 * @Time: 2015-9-6 下午8:32:38 8 */ 9 public class TestInner { 10 11 /** 12 * @author shaobn 13 * @Describe : 14 * @param args 15 * @Time

java基础学习总结-接口

原文链接:http://www.cnblogs.com/xdp-gacl/p/3651121.html 一.接口的概念 JAVA是只支持单继承的,但现实之中存在多重继承这种现象,如"金丝猴是一种动物",金丝猴从动物这个类继承,同时"金丝猴是一种值钱的东西",金丝猴从"值钱的东西"这个类继承,同时"金丝猴是一种应该受到保护的东西",金丝猴从"应该受到保护的东西"这个类继承.这样金丝猴可以同时从 "动

Java内部类引用外部类中的局部变量为何必须是final问题解析

今天编写一个多线程程序,发现在方法内定义内部类时,如果内部类调用了方法中的变量,那么该变量必须申明为final类型,百思不得其解,后来想到应该 是生命周期的原因,因为方法内定义的变量是局部变量,离开该方法,变量就失去了作用,也就会自动被消除,而内部类却不会离开它所在方法就失去作用,它有更 广的生命周期,下面通过一个实例加以说明: 如例中所示,在外部类Outer中声明了一个内部类TimerPrint,这个类中的方法引用了方法start中的一个局部变量testTxt 逻辑上:因为该内部类出现在一个方

java 内部类学习

类和内部类的关系就如同人和心脏的关系. 实例1:内部类的基本结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 //外部类 class Out {     private int age = 12;          //内部类     class In {         public void print() {             System.out.println(age);         }    

java.util.stream.Stream 接口中的常用方法

流模型的操作很丰富,下面介绍一些常用的API.这些方法可以被分成两种: 延迟方法 返回值类型仍然是 Stream 接口自身类型的方法,因此支持链式调用.(除了终结方法外,其余方 法均为延迟方法.) 终结方法 返回值类型不再是 Stream 接口自身类型的方法,因此不再支持类似 StringBuilder 那样的链式调 用.在这里介绍的终结方法包括 count 和 forEach 方法. 逐一处理:forEach 虽然方法名字叫 forEach ,但是与for循环中的“for-each”昵称不同.