三个接口一个注解
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");
}
}
运行结果: