模仿netty实现责任链模式

三个接口一个注解

public interface Handler {
    /**
     * 真正的业务处理操作
     *
     * @param ctx
     * @param msg
     */
    void handler(DefaultHandlerContext ctx, Object msg);

    /**
     * 结束处理
     *
     * @param ctx
     */
    void stopHandler(DefaultHandlerContext ctx);
}

public interface HandlerContext {

    String name();

    DefaultHandlerContext fireHandler(Object msg);

    DefaultHandlerContext fireStop();

    boolean isRemoved();

    Handler handler();

    Pipeline pipeline();
}
public interface Pipeline {

    /**
     * 向链表开始位置增加handler
     * @param name
     * @param handler
     * @return Pipeline
     */
    Pipeline addFirst(String name, Handler handler);

    Pipeline addLast(String name, Handler handler);

    Pipeline fireHandler(Object msg);

    Pipeline fireStop(Handler handler);
 
    Handler remove(String name);

    Handler remove(Handler handler);

    DefaultHandlerContext context(String name);

    DefaultHandlerContext context(Handler handler);
}
@Inherited
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Sharable {
    // no value
}

接口实现

public class DefaultHandlerContext implements HandlerContext {
    private Handler handler;
    DefaultHandlerContext next;
    DefaultHandlerContext prev;
    private final Pipeline pipeline;
    private final String name;
    private volatile int handlerState = INIT;
    private static final int INIT = 0;
    private static final int ADD_COMPLETE = 1;
    private static final int REMOVE_COMPLETE = 2;
    private static final AtomicIntegerFieldUpdater<DefaultHandlerContext> HANDLER_STATE_UPDATER =
            AtomicIntegerFieldUpdater.newUpdater(DefaultHandlerContext.class, "handlerState");

    public DefaultHandlerContext(Pipeline pipeline, Handler handler, String name) {
        this.pipeline = pipeline;
        this.handler = handler;
        this.name = name;
    }

    public DefaultHandlerContext(Pipeline pipeline, String name) {
        this.pipeline = pipeline;
        this.name = name;
    }

    @Override
    public String name() {
        return name;
    }


    static void invokeHandler(final DefaultHandlerContext next, Object msg) {
        next.invokeHandler(msg);
    }

    static void invokeStop(final DefaultHandlerContext next) {
        next.invokeStop();
    }

    @Override
    public boolean isRemoved() {
        return handlerState == REMOVE_COMPLETE;
    }

    private void invokeHandler(Object msg) {
        if (invokeHandler()) {
            try {
                handler().handler(this, msg);
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("An exception  was thrown by a user handler's exceptionCaught()");
            }
        } else {
            fireHandler(msg);
        }
    }

    private void invokeStop() {
        if (invokeStopThis()) {
            try {
                handler().stopHandler(this);
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("An exception  was thrown by a user handler's exceptionCaught()");
            }
        } else {
            fireStop();
        }
    }

    @Override
    public DefaultHandlerContext fireHandler(final Object msg) {
        Optional.ofNullable(findNextContext())
                .ifPresent(next -> invokeHandler(next, msg));
        return this;
    }

    @Override
    public DefaultHandlerContext fireStop() {
        Optional.ofNullable(findNextContext())
                .ifPresent(next -> invokeStop(next));
        return this;
    }


    private DefaultHandlerContext findNextContext() {
        return this.next;
    }

    @Override
    public Handler handler() {
        return handler;
    }

    @Override
    public Pipeline pipeline() {
        return pipeline;
    }

    final void setRemoved() {
        for (; ; ) {
            int oldState = handlerState;
            if (oldState == INIT || HANDLER_STATE_UPDATER.compareAndSet(this, oldState, REMOVE_COMPLETE)) {
                return;
            }
        }
    }

    final void setAddComplete() {
        for (; ; ) {
            int oldState = handlerState;
            if (oldState == REMOVE_COMPLETE || HANDLER_STATE_UPDATER.compareAndSet(this, oldState, ADD_COMPLETE)) {
                return;
            }
        }
    }

    private boolean invokeHandler() {
        int handlerState = this.handlerState;
        return handlerState == ADD_COMPLETE;
    }

    private boolean invokeStopThis() {
        int handlerState = this.handlerState;
        return handlerState == ADD_COMPLETE;
    }
}



public class HeadContext extends DefaultHandlerContext implements Handler {
    public HeadContext(Pipeline pipeline) {
        super(pipeline, "head");
        setAddComplete();
    }

    @Override
    public void handler(DefaultHandlerContext ctx, Object msg)  {
        try {
            System.err.println("head");
        } finally {
            ctx.fireHandler(msg);
        }
    }

    @Override
    public void stopHandler(DefaultHandlerContext ctx) {
        try {
            ctx.pipeline().remove(handler());
        } finally {
            ctx.fireStop();
        }
    }


    @Override
    public Handler handler() {
        return this;
    }
}





public class TailContext extends DefaultHandlerContext implements Handler {
    public TailContext(Pipeline pipeline) {
        super(pipeline, "tail");
        setAddComplete();
    }

    @Override
    public void handler(DefaultHandlerContext ctx, Object msg) {
        System.err.println("tail");
    }


    @Override
    public Handler handler() {
        return this;
    }

    @Override
    public void stopHandler(DefaultHandlerContext ctx) {
        //loop
    }
}

public class DefaultPipeline implements Pipeline {

    final DefaultHandlerContext head;
    final DefaultHandlerContext tail;

    public DefaultPipeline() {
        tail = new TailContext(this);
        head = new HeadContext(this);

        head.next = tail;
        tail.prev = head;
    }


    @Override
    public Pipeline addFirst(String name, Handler handler) {
        final DefaultHandlerContext newCtx;
        synchronized (this) {
            newCtx = newContext(filterName(name), handler);
            addFirst0(newCtx);
        }
        newCtx.setAddComplete();
        return this;
    }

    @Override
    public Pipeline addLast(String name, Handler handler) {
        final DefaultHandlerContext newCtx;
        synchronized (this) {
            newCtx = newContext(filterName(name), handler);
            addLast0(newCtx);
        }
        newCtx.setAddComplete();
        return this;
    }

    @Override
    public Pipeline fireHandler(Object msg) {
        DefaultHandlerContext.invokeHandler(head, msg);
        return this;
    }

    @Override
    public Pipeline fireStop(Handler handler) {
        DefaultHandlerContext.invokeStop(context(handler));
        return this;
    }

    @Override
    public Handler remove(String name) {
        return remove(getContextOrDie(name)).handler();
    }

    @Override
    public Handler remove(Handler handler) {
        return remove(getContextOrDie(handler)).handler();
    }

    @Override
    public final DefaultHandlerContext context(String name) {
        if (name == null) {
            throw new NullPointerException("name");
        }

        return context0(name);
    }

    @Override
    public DefaultHandlerContext context(Handler handler) {
        if (handler == null) {
            throw new NullPointerException("handler");
        }
        DefaultHandlerContext ctx = head.next;
        for (; ; ) {

            if (ctx == null) {
                return null;
            }

            if (ctx.handler() == handler) {
                return ctx;
            }

            ctx = ctx.next;
        }
    }

    private DefaultHandlerContext remove(final DefaultHandlerContext ctx) {
        if (ctx != head && ctx != tail) {
            synchronized (this) {
                remove0(ctx);
            }
            ctx.setRemoved();
        }
        return ctx;
    }


    private String filterName(String name) {
        if (name == null) {
            throw new IllegalArgumentException(" handler name is null");
        }
        if (context0(name) != null) {
            throw new IllegalArgumentException("Duplicate handler name: " + name);
        }
        return name;
    }

    private DefaultHandlerContext getContextOrDie(String name) {
        DefaultHandlerContext ctx = context(name);
        if (ctx == null) {
            throw new NoSuchElementException(name);
        } else {
            return ctx;
        }
    }


    private DefaultHandlerContext getContextOrDie(Handler handler) {
        DefaultHandlerContext ctx = context(handler);
        if (ctx == null) {
            throw new NoSuchElementException(handler.getClass().getName());
        } else {
            return ctx;
        }
    }

    private DefaultHandlerContext context0(String name) {
        DefaultHandlerContext context = head.next;
        while (context != tail) {
            if (context.name().equals(name)) {
                return context;
            }
            context = context.next;
        }
        return null;
    }

    private static void remove0(DefaultHandlerContext ctx) {
        DefaultHandlerContext prev = ctx.prev;
        DefaultHandlerContext next = ctx.next;
        prev.next = next;
        next.prev = prev;
    }

    private DefaultHandlerContext newContext(String name, Handler handler) {
        return new DefaultHandlerContext(this, handler, name);
    }

    private void addFirst0(DefaultHandlerContext newCtx) {
        DefaultHandlerContext nextCtx = head.next;
        newCtx.prev = head;
        newCtx.next = nextCtx;
        head.next = newCtx;
        nextCtx.prev = newCtx;
    }

    private void addLast0(DefaultHandlerContext newCtx) {
        DefaultHandlerContext preCtx = tail.prev;
        newCtx.next = tail;
        newCtx.prev = preCtx;
        tail.prev = newCtx;
        preCtx.next = newCtx;
    }
}

@Sharable
public class TestHandler implements Handler {

    @Override
    public void handler(DefaultHandlerContext ctx, Object msg) {
        try {
            System.err.println("handler 1 :" + msg);
            System.err.println(this.hashCode());
        } finally {
            ctx.fireHandler(msg);
        }
    }

    @Override
    public void stopHandler(DefaultHandlerContext ctx) {
        try {
            ctx.pipeline().remove(this);
            System.err.println("stop testHandler1");
        } finally {
            ctx.fireStop();
        }
    }
}



public class TestHandler2 implements Handler {
    @Override
    public void handler(DefaultHandlerContext ctx, Object msg) {
        try {
            System.err.println("handler 2:" + msg);
            System.err.println(this.hashCode());
        } finally {
            ctx.fireHandler(msg);
        }
    }

    @Override
    public void stopHandler(DefaultHandlerContext ctx) {
        try {
            ctx.pipeline().remove(this);
            System.err.println("stop testHandler2");
        } finally {
            ctx.fireStop();
        }
    }
}

创建pipeline、测试demo

public final class PipelineFactory {

    public static final Map<String, Handler> SHAREABLE_HANDLER_MAP = new HashMap<>();

    static {
        Set<Class<?>> set = ClassUtil.scanPackage("com.dzl.center.handler.handler");
        for (Class<?> aClass : set) {
            Class<Handler> handlerClass = (Class<Handler>) aClass;
            if (isSharable(handlerClass)) {
                try {
                    SHAREABLE_HANDLER_MAP.put(handlerClass.getSimpleName(), handlerClass.newInstance());
                } catch (InstantiationException | IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @SafeVarargs
    public static Pipeline newPipeline(Class<? extends Handler>... clazz) throws IllegalAccessException, InstantiationException {
        Pipeline pipeline = new DefaultPipeline();
        for (Class<? extends Handler> handlerClass : clazz) {
            String className = handlerClass.getSimpleName();
            addLastByClass(pipeline, className, handlerClass);
        }
        return pipeline;
    }

    public static Pipeline newPipeline(Handler... handlers) {
        Pipeline pipeline = new DefaultPipeline();
        for (Handler handler : handlers) {
            pipeline.addLast(handler.getClass().getSimpleName(), handler);
        }
        return pipeline;
    }

    public static Pipeline newPipeline(String... handlerClassNames) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        Pipeline pipeline = new DefaultPipeline();
        for (String handlerClassName : handlerClassNames) {
            Class<? extends Handler> handlerClass = (Class<? extends Handler>) ReflectUtil.forName(handlerClassName);
            addLastByClass(pipeline, handlerClassName, handlerClass);
        }
        return pipeline;
    }

    private static void addLastByClass(Pipeline pipeline, String handlerClassName, Class<? extends Handler> handlerClass) throws InstantiationException, IllegalAccessException {
        Handler handler;
        if ((handler = SHAREABLE_HANDLER_MAP.get(handlerClassName)) == null) {
            handler = handlerClass.newInstance();
        }
        pipeline.addLast(handlerClassName, handler);
    }

    private static boolean isSharable(Class<Handler> clazz) {
        return clazz.isAnnotationPresent(Sharable.class);
    }
}





public class Test {

    public static void main(String[] args) throws InstantiationException, IllegalAccessException {


        Pipeline pipeline = PipelineFactory.newPipeline(TestHandler.class, TestHandler2.class);
        pipeline.fireHandler("dai");

        Pipeline pipeline2 = PipelineFactory.newPipeline(TestHandler.class, TestHandler2.class);
        pipeline2.fireHandler("dai");
    }
}

运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值