基于Spring&责任链模式的字符串过滤组件
1、责任链模式
使多个对象都有机会处理请求,从而避免请求的发送者与接受者之间的耦合关系。将这个对象练成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止。
1.1 定义接口,说明处理的方式方法,需要维护一个本身的引用,这样方便调用下一个处理器。
package 职责链模式;
public abstract class Handler {
protected Handler successor;
public void SetSuccessor(Handler handler) {
this.successor = handler;
}
//处理请求的抽象方法
public abstract void HandleRequest(int request);
}
1.2 各种处理方法,实现该抽象类。
package 职责链模式;
public class ConcreteHandler extends Handler {
@Override
public void HandleRequest(int request) {
if (request >= 0 && request < 10) {
System.out.println(this.getClass().getName() + "已经处理了请求!"+request);
} else if (successor != null) {
successor.HandleRequest(request);
}
}
}
package 职责链模式;
public class ConcreteHandler2 extends Handler {
@Override
public void HandleRequest(int request) {
if (request >= 10 && request < 20) {
System.out.println(this.getClass().getName() + "已经处理了请求!"+request);
} else if (successor != null) {
successor.HandleRequest(request);
}
}
}
package 职责链模式;
public class ConcreteHandler3 extends Handler {
@Override
public void HandleRequest(int request) {
if (request >= 20 && request < 30) {
System.out.println(this.getClass().getName() + "已经处理了请求!"+request);
} else if (successor != null) {
successor.HandleRequest(request);
}
}
}
这里代码很简单,我就不解释了。然后在主函数中,把它们串成一条线,并进行匹配:
package 职责链模式;
public class MainTest {
public static void main(String[] args) {
Handler h1Handler = new ConcreteHandler();
Handler h2Handler = new ConcreteHandler2();
Handler h3Handler = new ConcreteHandler3();
h1Handler.SetSuccessor(h2Handler);
h2Handler.SetSuccessor(h3Handler);
int [] request = {2,4,15,22,18,3,27,20};
for (int i : request) {
h1Handler.HandleRequest(i);
}
}
}
这里就会顺序的匹配了。
1.3 责任链模式的好处
当我们提交一个请求的时候,请求沿着链进行传递,直到有一个对象负责处理他。我们只需要保存下一个对象的一个引用即可。降低了程序的耦合,并且可以灵活的规定处理器的顺序。
2、spring组件
2.1 依赖查找
当我们的ioc容器中存在一个接口(抽象类)多个实现,就可以使用Map来注入多个实现的对象;
private Map<String, StringMatchHandler> autowiredStringMatchHandlerMap;
顶层接口:规定字符串匹配的类型:
package com.panzh.responsable;
public interface StringMatchHandler {
boolean match(String str);
}
抽象类:实现传递set的方法:
package com.panzh.responsable;
public abstract class AbstractStringHandler implements StringMatchHandler {
protected AbstractStringHandler successor;
public void setSuccessor(AbstractStringHandler successor) {
this.successor = successor;
}
}
具体的两个实现类(这里的实现类可以进行自己的定义)
package com.panzh.responsable;
import com.panzh.responsable.annation.MatchOrder;
import org.springframework.stereotype.Component;
@Component
@MatchOrder(value = 2)
public class StringLengthMatch extends AbstractStringHandler {
@Override
public boolean match(String str) {
if (str.length() >= 1 && str.length() < 10){
return true;
}else if (successor != null){
return successor.match(str);
}else {
return false;
}
}
}
package com.panzh.responsable;
import com.panzh.responsable.annation.MatchOrder;
import org.springframework.stereotype.Component;
@Component
@MatchOrder(value = 1)
public class StringStarWithMatch extends AbstractStringHandler {
@Override
public boolean match(String str) {
if (str.startsWith("java")){
return true;
}else if (successor != null){
return successor.match(str);
}
return false;
}
}
实际的匹配器,如需添加功能,可以在这里面添加代码:
package com.panzh;
import com.panzh.responsable.AbstractStringHandler;
import com.panzh.responsable.StringMatchHandler;
import com.panzh.responsable.annation.MatchOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.*;
@Component
public class MainBean {
//进行依赖的查找。
@Autowired
private Map<String, StringMatchHandler> autowiredStringMatchHandlerMap;
//需要进行匹配的字符串。
// private String reg;
private List<StringMatchHandler> stringMatchHandlerCache;
private StringMatchHandler rootStringMatchChain;
// public void getMap(){
// autowiredStringMatchHandlerMap.forEach((String String,Object Object)->{
// System.out.println(String);
// });
// }
public boolean MatchString(String str){
//根据优先级进行排序
sortResponsibilityChain(autowiredStringMatchHandlerMap.values());
//生成过滤器链
createStringMatchChain(stringMatchHandlerCache);
//执行过滤的操作
return rootStringMatchChain.match(str);
}
private void createStringMatchChain(List<StringMatchHandler> stringMatchHandlerCache) {
rootStringMatchChain = stringMatchHandlerCache.get(0);
for (int i = 0 ; i < stringMatchHandlerCache.size() - 1 ; i++){
((AbstractStringHandler)stringMatchHandlerCache.get(i)).setSuccessor(((AbstractStringHandler)stringMatchHandlerCache.get(i+1)));
}
}
private void sortResponsibilityChain(Collection<StringMatchHandler> values) {
transformStringMatchCache(values);
cheakStringMatchHandlerCache(stringMatchHandlerCache);
//sort stringMatchHandlerCache。
Collections.sort(stringMatchHandlerCache,((StringMatchHandler s1, StringMatchHandler s2)->{
int value1 = s1.getClass().getAnnotation(MatchOrder.class).value();
int value2 = s2.getClass().getAnnotation(MatchOrder.class).value();
if (value1 == value2){
return 0;
}
return value1 > value2 ? 1 : -1;
}));
}
private void transformStringMatchCache(Collection<StringMatchHandler> values) {
if (stringMatchHandlerCache == null){
stringMatchHandlerCache = new ArrayList<>();
}
for (StringMatchHandler value : values) {
stringMatchHandlerCache.add(value);
}
}
private void cheakStringMatchHandlerCache(List<StringMatchHandler> stringMatchHandlerCache) {
for (StringMatchHandler stringMatchHandler : stringMatchHandlerCache) {
if (stringMatchHandler.getClass().getAnnotation(MatchOrder.class) == null){
throw new RuntimeException("StringMatchHandler Class must have MatchOrder Anotaion");
}
}
}
}
我们使用的时候,就可以自己定义类实现AbstractStringHandler抽象类,然后添加MatchOrder注解。并加入ioc容器即可。可以自由的进行扩展。需要自己定义一个MatchOrder注解哈,忘记在文档中说明了。