java:责任链设计模式配合Spring@Order注解使用场景
1 前言
java的责任链模式,经典使用的场景为SpringMVC的doDispatch下,针对请求的过滤链式行为。实际开发场景中,可配合Spring的@Order注解,定义1个有顺序的链式Components列表,根据Components列表的顺序依次处理,如果中途存在处理失败的Component,则终止(或过滤,依赖实际场景即可)整个处理过程,实际使用方式见如下。
2 使用
链式调用的client接口:
public interface IHandleChain {
boolean handleChain();
}
链式调用的client抽象类:
package com.xiaoxu.handleChain;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import javax.annotation.PostConstruct;
import java.util.List;
/**
* @author xiaoxu
* @date 2023-01-09
* java_demo2:com.xiaoxu.handleChain.AbstractHandleChain
*/
public abstract class AbstractHandleChain implements IHandleChain{
@Autowired
List<IHandle> handlers;
IHandle handler;
@PostConstruct
public void postHandlers(){
if(CollectionUtils.isEmpty(handlers)){
throw new RuntimeException("handlers should not be null or empty.");
}
System.out.println("开始执行postHandlers...");
IHandle currentHandler;
IHandle nextHandler;
for (int i = 0; i < handlers.size(); i++) {
if(i == 0){
handler = handlers.get(0);
}else{
currentHandler = handlers.get(i-1);
nextHandler = handlers.get(i);
currentHandler.setNextIHandle(nextHandler);
}
}
System.out.println("handleChain:"+handler);
}
protected boolean handle(){
if(null == this.handler){
throw new RuntimeException("handler should not be null.");
}
return this.handler.handle();
}
}
上述抽象类获取的链式client处理对象:
链式调用Client:
package com.xiaoxu.handleChain;
import org.springframework.stereotype.Component;
/**
* @author xiaoxu
* @date 2023-01-09
* java_demo2:com.xiaoxu.handleChain.HandleChainClient
*/
@Component
public class HandleChainClient extends AbstractHandleChain{
@Override
public boolean handleChain() {
boolean res;
if(res = this.handle()){
System.out.println("全部业务处理成功!");
}else{
System.out.println("事务中途处理失败!!!");
}
return res;
}
}
IHandle接口:
public interface IHandle {
void setNextIHandle(IHandle iHandle);
IHandle getNextIHandle();
boolean doHandle();
boolean handle();
}
IHandle抽象类:
package com.xiaoxu.handleChain;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
* @author xiaoxu
* @date 2023-01-10
* java_demo2:com.xiaoxu.handleChain.AbstractIHandle
*/
public abstract class AbstractIHandle implements IHandle{
IHandle nextIHandle;
@Override
public void setNextIHandle(IHandle iHandle) {
this.nextIHandle = iHandle;
}
@Override
public IHandle getNextIHandle() {
return this.nextIHandle;
}
@Override
public boolean handle() {
boolean res = this.doHandle();
if(res){
if(null != getNextIHandle()){
return getNextIHandle().handle();
}
return true;
}
return false;
}
@Override
public String toString(){
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}
IHandle的具体处理实现类:
链式处理step1:前置检查
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* @author xiaoxu
* @date 2023-01-09
* java_demo2:com.xiaoxu.handleChain.PreHandle
*/
@Component
@Order(value = 1)
public class PreHandle extends AbstractIHandle{
@Override
public boolean doHandle() {
System.out.println("前置检查...");
return true;
}
}
链式处理step2:安全检查
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* @author xiaoxu
* @date 2023-01-09
* java_demo2:com.xiaoxu.handleChain.CheckSecurityHandle
*/
@Component
@Order(value = 2)
public class CheckSecurityHandle extends AbstractIHandle{
@Override
public boolean doHandle() {
System.out.println("安全检查...");
return true;
}
}
链式处理step3:业务处理
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* @author xiaoxu
* @date 2023-01-09
* java_demo2:com.xiaoxu.handleChain.ServiceHandle
*/
@Component
@Order(value = 3)
public class ServiceHandle extends AbstractIHandle{
@Override
public boolean doHandle() {
System.out.println("业务处理...");
return true;
}
}
链式处理step4:后置处理
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* @author xiaoxu
* @date 2023-01-09
* java_demo2:com.xiaoxu.handleChain.PostHandle
*/
@Component
@Order(value = 4)
public class PostHandle extends AbstractIHandle{
@Override
public boolean doHandle() {
System.out.println("后置处理...");
return true;
}
}
编写单测执行:
import com.xiaoxu.MainApplication;
import com.xiaoxu.handleChain.HandleChainClient;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @author xiaoxu
* @date 2023-01-09
* java_demo2:PACKAGE_NAME.TestHandle
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MainApplication.class)
public class TestHandle {
@Autowired
HandleChainClient client;
@Test
public void test_01(){
boolean b = client.handleChain();
System.out.println("结果为:" + b);
}
}
执行结果如下,可见达到了链式处理的效果:
若将业务处理的返回改为false后再次执行:
结果如下所示: