一、责任链模式
顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。
在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
二、介绍
- 意图:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
- 主要解决:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。
- 何时使用:在处理消息的时候以过滤很多道。
- 如何解决:拦截的类都实现统一接口。
- 关键代码:Handler 里面聚合它自己,在 HandlerRequest 里判断是否合适,如果没达到条件则向下传递,向谁传递之前 set 进去。
- 应用实例:
-
- 1、红楼梦中的"击鼓传花"。
-
- 2、JS 中的事件冒泡。
-
- 3、JAVA WEB 中 Apache Tomcat 对 Encoding 的处理,Struts2 的拦截器,jsp servlet 的 Filter。
- 优点:
-
- 1、降低耦合度。它将请求的发送者和接收者解耦。
-
- 2、简化了对象。使得对象不需要知道链的结构。
-
- 3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
-
- 4、增加新的请求处理类很方便。
- 缺点:
-
- 1、不能保证请求一定被接收。
-
- 2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
-
- 3、可能不容易观察运行时的特征,有碍于除错。
- 使用场景:
-
- 1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
-
- 2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
-
- 3、可动态指定一组对象处理请求。
- 注意事项:在 JAVA WEB 中遇到很多应用。
三、简介
本文将结合个性化推荐系统中的广告推荐流程来讲解责任链模式,广告位经过定义的责任链
预处理—>召回模块—>粗排序模块—>精排序模块—>规则模块—> 资讯模块—>后处理:上报信息
得到个性化的推荐广告位,来讲解责任链模式如何在实际生产中使用。
四、配置信息
- jdk 版本:jdk8
- 框架:springboot
五、maven配置
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.17.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<version>1.5.13.RELEASE</version>
<scope>test</scope>
</dependency>
六、springboot 启动类添加启动时加载配置文件
/**
* <code>Details determine success.</code>
* by Liang ZC., Phd@Stanford
*
* @author LIANGZHICHENG
* @date 2019-8-22 19:33
* @see http://www.stanford.edu
*/
@ImportResource({"classpath*:bidding-beans.xml"})
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
七、责任链模式配置文件bidding-beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<!-- 广告推荐流程 -->
<util:list id="dspServiceHandlers" value-type="com.pingan.ai.handler.DspServiceHandler">
<!-- 预处理 -->
<ref bean="preproccessHandler"/>
<!-- 召回模块 -->
<ref bean="recallHandler"/>
<!-- 粗排序模块 -->
<ref bean="roughSortHandler"/>
<!-- 精排序模块 -->
<ref bean="refinedSortHandler"/>
<!-- 规则模块 -->
<ref bean="ruleHandler"/>
<!-- 资讯模块 -->
<ref bean="feedHandler"/>
<!-- 后处理:上报信息 -->
<ref bean="reportLogHandler"/>
</util:list>
</beans>
八、处理信息BidSession
/**
* <code>Details determine success.</code>
* by Liang ZC., Phd@Stanford
*
* @author LIANGZHICHENG
* @date 2019-8-22 19:34
* @see http://www.stanford.edu
*/
@Data
public class BidSession {
/**
* 广告位
*/
private Map<String, Integer> slots;
}
/**
* <code>Details determine success.</code>
* by Liang ZC., Phd@Stanford
*
* @author LIANGZHICHENG
* @date 2019-8-23 15:21
* @see http://www.stanford.edu
*/
public enum SlotTypeEnum {
RECALL(1, "召回"),
ROUGH_SORT(2, "粗排序"),
REFINED_SORT(3, "精排序"),
RULE(4, "展控规则"),
FEED(5, "资讯"),
ILLEGAL_SLOT(Integer.MAX_VALUE, "非法广告位");
private Integer code;
private String value;
SlotTypeEnum(Integer code,
String value) {
this.code = code;
this.value = value;
}
public Integer getCode() {
return code;
}
public String getValue() {
return value;
}
public static String valueOf(Integer code) {
for (SlotTypeEnum slotTypeEnum : SlotTypeEnum.values()) {
if (slotTypeEnum.code.equals(code)) {
return slotTypeEnum.getValue();
}
}
throw new IllegalArgumentException("Code no found in SlotTypeEnum.");
}
}
九、定义处理接口DspServiceHandler
/**
* <code>Details determine success.</code>
* by Liang ZC., Phd@Stanford
*
* @author LIANGZHICHENG
* @date 2019-8-22 19:33
* @see http://www.stanford.edu
*/
public interface DspServiceHandler {
/**
* Deal with {@param session}.
*
* @param session
*/
void process(final BidSession session);
}
十、实现处理接口(定义具体的职责)
10.1 预处理模块(装载广告位)
import com.google.common.collect.Maps;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* <code>Details determine success.</code>
* by Liang ZC., Phd@Stanford
*
* @author LIANGZHICHENG
* @date 2019-8-22 19:36
* @see http://www.stanford.edu
*/
@Component
public class PreproccessHandler implements DspServiceHandler {
/*
* N777777777NO
* N7777777777777N
* M777777777777777N
* *N877777777D77777M
* N M77777777ONND777M
* MN777777777NN D777
* N7ZN777777777NN ~M7778
* N777777777777MMNN88777N
* N777777777777MNZZZ7777O
* DZN7777O77777777777777
* N7OONND7777777D77777N
* 8*M++++?N???$77777$
* M7++++N+M77777777N
* N77O777777777777$ M
* DNNM$$$$777777N D
* N*N:=N$777N7777M NZ
* 77Z::::N777777777 ODZZZ
* 77N::::::N77777777M NNZZZ$
* $777:::::::77777777MN ZM8ZZZZZ
* 777M::::::Z7777777Z77 N++ZZZZNN
* 7777M:::::M7777777$777M $++IZZZZM
* M777$:::::N777777*M7777M +++++ZZZDN
* NN$::::::7777$*M777777N N+++ZZZZNZ
* N::::::N:7*O:77777777 N++++ZZZZN
* M::::::::::::N77777777+ +?+++++ZZZM
* 8::::::::::::D77777777M O+++++ZZ
* ::::::::::::M777777777N O+?D
* M:::::::::::M77777777778 77=
* D=::::::::::N7777777777N 777
* INN===::::::=77777777777N I777N
* ?777N========N7777777777787M N7777
* 77777*D======N77777777777N777N? N777777
* I77777$$*N7===M$$77777777$77777777*MMZ77777777N
* $$$$$$$$$$*NIZN$$$$$$$$*M$$7777777777777777ON
* M$$$$$$$*M M$$$$$$$*N=N$$$$7777777$$*ND
* O77Z$$$$$$$ M$$$$$$$*MNI==*DNNNNM=~N
* 7 :N MNN$$$*M$ $$$777$8 8D8I
* NMM.:7O 777777778
* 7777777MN
* M NO .7:
* M : M
* 8
*/
// Constant matcher factory methods
/**
* Loading advertising space.
*
* @param session
*/
@Override
public void process(BidSession session) {
// prepare slots
Map<String, Integer> slots = Maps.newHashMap();
for (SlotTypeEnum slotTypeEnum : SlotTypeEnum.values()) {
slots.put(slotTypeEnum.getValue(), slotTypeEnum.getCode());
}
session.setSlots(slots);
}
}
10.2 召回模块(计算广告位召回率)
import java.util.Map;
/**
* <code>Details determine success.</code>
* by Liang ZC., Phd@Stanford
*
* @author LIANGZHICHENG
* @date 2019-8-23 14:42
* @see http://www.stanford.edu
*/
@Component
public class RecallHandler implements DspServiceHandler {
/*
* N777777777NO
* N7777777777777N
* M777777777777777N
* *N877777777D77777M
* N M77777777ONND777M
* MN777777777NN D777
* N7ZN777777777NN ~M7778
* N777777777777MMNN88777N
* N777777777777MNZZZ7777O
* DZN7777O77777777777777
* N7OONND7777777D77777N
* 8*M++++?N???$77777$
* M7++++N+M77777777N
* N77O777777777777$ M
* DNNM$$$$777777N D
* N*N:=N$777N7777M NZ
* 77Z::::N777777777 ODZZZ
* 77N::::::N77777777M NNZZZ$
* $777:::::::77777777MN ZM8ZZZZZ
* 777M::::::Z7777777Z77 N++ZZZZNN
* 7777M:::::M7777777$777M $++IZZZZM
* M777$:::::N777777*M7777M +++++ZZZDN
* NN$::::::7777$*M777777N N+++ZZZZNZ
* N::::::N:7*O:77777777 N++++ZZZZN
* M::::::::::::N77777777+ +?+++++ZZZM
* 8::::::::::::D77777777M O+++++ZZ
* ::::::::::::M777777777N O+?D
* M:::::::::::M77777777778 77=
* D=::::::::::N7777777777N 777
* INN===::::::=77777777777N I777N
* ?777N========N7777777777787M N7777
* 77777*D======N77777777777N777N? N777777
* I77777$$*N7===M$$77777777$77777777*MMZ77777777N
* $$$$$$$$$$*NIZN$$$$$$$$*M$$7777777777777777ON
* M$$$$$$$*M M$$$$$$$*N=N$$$$7777777$$*ND
* O77Z$$$$$$$ M$$$$$$$*MNI==*DNNNNM=~N
* 7 :N MNN$$$*M$ $$$777$8 8D8I
* NMM.:7O 777777778
* 7777777MN
* M NO .7:
* M : M
* 8
*/
// Constant matcher factory methods
/**
* Calculating Recall Advertising Places.
*
* @param session
*/
@Override
public void process(BidSession session) {
// slots
Map<String, Integer> slots = session.getSlots();
Integer slotType = slots.getOrDefault(SlotTypeEnum.RECALL.getValue(), Integer.MAX_VALUE);
System.out.println(SlotTypeEnum.valueOf(slotType));
}
}
10.3 粗排序模块(对广告位进行大致排序)
import java.util.Map;
/**
* <code>Details determine success.</code>
* by Liang ZC., Phd@Stanford
*
* @author LIANGZHICHENG
* @date 2019-8-23 14:43
* @see http://www.stanford.edu
*/
@Component
public class RoughSortHandler implements DspServiceHandler {
/*
* N777777777NO
* N7777777777777N
* M777777777777777N
* *N877777777D77777M
* N M77777777ONND777M
* MN777777777NN D777
* N7ZN777777777NN ~M7778
* N777777777777MMNN88777N
* N777777777777MNZZZ7777O
* DZN7777O77777777777777
* N7OONND7777777D77777N
* 8*M++++?N???$77777$
* M7++++N+M77777777N
* N77O777777777777$ M
* DNNM$$$$777777N D
* N*N:=N$777N7777M NZ
* 77Z::::N777777777 ODZZZ
* 77N::::::N77777777M NNZZZ$
* $777:::::::77777777MN ZM8ZZZZZ
* 777M::::::Z7777777Z77 N++ZZZZNN
* 7777M:::::M7777777$777M $++IZZZZM
* M777$:::::N777777*M7777M +++++ZZZDN
* NN$::::::7777$*M777777N N+++ZZZZNZ
* N::::::N:7*O:77777777 N++++ZZZZN
* M::::::::::::N77777777+ +?+++++ZZZM
* 8::::::::::::D77777777M O+++++ZZ
* ::::::::::::M777777777N O+?D
* M:::::::::::M77777777778 77=
* D=::::::::::N7777777777N 777
* INN===::::::=77777777777N I777N
* ?777N========N7777777777787M N7777
* 77777*D======N77777777777N777N? N777777
* I77777$$*N7===M$$77777777$77777777*MMZ77777777N
* $$$$$$$$$$*NIZN$$$$$$$$*M$$7777777777777777ON
* M$$$$$$$*M M$$$$$$$*N=N$$$$7777777$$*ND
* O77Z$$$$$$$ M$$$$$$$*MNI==*DNNNNM=~N
* 7 :N MNN$$$*M$ $$$777$8 8D8I
* NMM.:7O 777777778
* 7777777MN
* M NO .7:
* M : M
* 8
*/
// Constant matcher factory methods
/**
* Preliminary sorting of advertising space.
*
* @param session
*/
@Override
public void process(BidSession session) {
// slots
Map<String, Integer> slots = session.getSlots();
Integer slotType = slots.getOrDefault("", Integer.MAX_VALUE);
System.out.println(SlotTypeEnum.valueOf(slotType));
}
}
10.4 精排模块(对广告位进行精细化排序,例:去除非法广告位)
import java.util.Map;
/**
* <code>Details determine success.</code>
* by Liang ZC., Phd@Stanford
*
* @author LIANGZHICHENG
* @date 2019-8-23 14:44
* @see http://www.stanford.edu
*/
@Component
public class RefinedSortHandler implements DspServiceHandler {
/*
* N777777777NO
* N7777777777777N
* M777777777777777N
* *N877777777D77777M
* N M77777777ONND777M
* MN777777777NN D777
* N7ZN777777777NN ~M7778
* N777777777777MMNN88777N
* N777777777777MNZZZ7777O
* DZN7777O77777777777777
* N7OONND7777777D77777N
* 8*M++++?N???$77777$
* M7++++N+M77777777N
* N77O777777777777$ M
* DNNM$$$$777777N D
* N*N:=N$777N7777M NZ
* 77Z::::N777777777 ODZZZ
* 77N::::::N77777777M NNZZZ$
* $777:::::::77777777MN ZM8ZZZZZ
* 777M::::::Z7777777Z77 N++ZZZZNN
* 7777M:::::M7777777$777M $++IZZZZM
* M777$:::::N777777*M7777M +++++ZZZDN
* NN$::::::7777$*M777777N N+++ZZZZNZ
* N::::::N:7*O:77777777 N++++ZZZZN
* M::::::::::::N77777777+ +?+++++ZZZM
* 8::::::::::::D77777777M O+++++ZZ
* ::::::::::::M777777777N O+?D
* M:::::::::::M77777777778 77=
* D=::::::::::N7777777777N 777
* INN===::::::=77777777777N I777N
* ?777N========N7777777777787M N7777
* 77777*D======N77777777777N777N? N777777
* I77777$$*N7===M$$77777777$77777777*MMZ77777777N
* $$$$$$$$$$*NIZN$$$$$$$$*M$$7777777777777777ON
* M$$$$$$$*M M$$$$$$$*N=N$$$$7777777$$*ND
* O77Z$$$$$$$ M$$$$$$$*MNI==*DNNNNM=~N
* 7 :N MNN$$$*M$ $$$777$8 8D8I
* NMM.:7O 777777778
* 7777777MN
* M NO .7:
* M : M
* 8
*/
// Constant matcher factory methods
/**
* Fine Sorting of Advertising Places.
*
* @param session
*/
@Override
public void process(BidSession session) {
// slots
Map<String, Integer> slots = session.getSlots();
Integer slotType = slots.getOrDefault(SlotTypeEnum.REFINED_SORT.getValue(), Integer.MAX_VALUE);
System.out.println(SlotTypeEnum.valueOf(slotType));
}
}
10.5 展控规则模块(进行个性化推荐)
import java.util.Map;
/**
* <code>Details determine success.</code>
* by Liang ZC., Phd@Stanford
*
* @author LIANGZHICHENG
* @date 2019-8-23 14:45
* @see http://www.stanford.edu
*/
@Component
public class RuleHandler implements DspServiceHandler {
/*
* N777777777NO
* N7777777777777N
* M777777777777777N
* *N877777777D77777M
* N M77777777ONND777M
* MN777777777NN D777
* N7ZN777777777NN ~M7778
* N777777777777MMNN88777N
* N777777777777MNZZZ7777O
* DZN7777O77777777777777
* N7OONND7777777D77777N
* 8*M++++?N???$77777$
* M7++++N+M77777777N
* N77O777777777777$ M
* DNNM$$$$777777N D
* N*N:=N$777N7777M NZ
* 77Z::::N777777777 ODZZZ
* 77N::::::N77777777M NNZZZ$
* $777:::::::77777777MN ZM8ZZZZZ
* 777M::::::Z7777777Z77 N++ZZZZNN
* 7777M:::::M7777777$777M $++IZZZZM
* M777$:::::N777777*M7777M +++++ZZZDN
* NN$::::::7777$*M777777N N+++ZZZZNZ
* N::::::N:7*O:77777777 N++++ZZZZN
* M::::::::::::N77777777+ +?+++++ZZZM
* 8::::::::::::D77777777M O+++++ZZ
* ::::::::::::M777777777N O+?D
* M:::::::::::M77777777778 77=
* D=::::::::::N7777777777N 777
* INN===::::::=77777777777N I777N
* ?777N========N7777777777787M N7777
* 77777*D======N77777777777N777N? N777777
* I77777$$*N7===M$$77777777$77777777*MMZ77777777N
* $$$$$$$$$$*NIZN$$$$$$$$*M$$7777777777777777ON
* M$$$$$$$*M M$$$$$$$*N=N$$$$7777777$$*ND
* O77Z$$$$$$$ M$$$$$$$*MNI==*DNNNNM=~N
* 7 :N MNN$$$*M$ $$$777$8 8D8I
* NMM.:7O 777777778
* 7777777MN
* M NO .7:
* M : M
* 8
*/
// Constant matcher factory methods
/**
* Deal with slot {@param session} by using rule , you can config some rule to control the slots.
*
* @param session
*/
@Override
public void process(BidSession session) {
// slots
Map<String, Integer> slots = session.getSlots();
Integer slotType = slots.getOrDefault("", Integer.MAX_VALUE);
System.out.println(SlotTypeEnum.valueOf(slotType));
}
}
10.6 资讯模块(得到最终可以展示的广告位)
import java.util.Map;
/**
* <code>Details determine success.</code>
* by Liang ZC., Phd@Stanford
*
* @author LIANGZHICHENG
* @date 2019-8-23 14:46
* @see http://www.stanford.edu
*/
@Component
public class FeedHandler implements DspServiceHandler {
/*
* N777777777NO
* N7777777777777N
* M777777777777777N
* *N877777777D77777M
* N M77777777ONND777M
* MN777777777NN D777
* N7ZN777777777NN ~M7778
* N777777777777MMNN88777N
* N777777777777MNZZZ7777O
* DZN7777O77777777777777
* N7OONND7777777D77777N
* 8*M++++?N???$77777$
* M7++++N+M77777777N
* N77O777777777777$ M
* DNNM$$$$777777N D
* N*N:=N$777N7777M NZ
* 77Z::::N777777777 ODZZZ
* 77N::::::N77777777M NNZZZ$
* $777:::::::77777777MN ZM8ZZZZZ
* 777M::::::Z7777777Z77 N++ZZZZNN
* 7777M:::::M7777777$777M $++IZZZZM
* M777$:::::N777777*M7777M +++++ZZZDN
* NN$::::::7777$*M777777N N+++ZZZZNZ
* N::::::N:7*O:77777777 N++++ZZZZN
* M::::::::::::N77777777+ +?+++++ZZZM
* 8::::::::::::D77777777M O+++++ZZ
* ::::::::::::M777777777N O+?D
* M:::::::::::M77777777778 77=
* D=::::::::::N7777777777N 777
* INN===::::::=77777777777N I777N
* ?777N========N7777777777787M N7777
* 77777*D======N77777777777N777N? N777777
* I77777$$*N7===M$$77777777$77777777*MMZ77777777N
* $$$$$$$$$$*NIZN$$$$$$$$*M$$7777777777777777ON
* M$$$$$$$*M M$$$$$$$*N=N$$$$7777777$$*ND
* O77Z$$$$$$$ M$$$$$$$*MNI==*DNNNNM=~N
* 7 :N MNN$$$*M$ $$$777$8 8D8I
* NMM.:7O 777777778
* 7777777MN
* M NO .7:
* M : M
* 8
*/
// Constant matcher factory methods
/**
* Information Advertising.
*
* @param session
*/
@Override
public void process(BidSession session) {
// slots
Map<String, Integer> slots = session.getSlots();
Integer slotType = slots.getOrDefault(SlotTypeEnum.FEED.getValue(), Integer.MAX_VALUE);
System.out.println(SlotTypeEnum.valueOf(slotType));
}
}
10.7 上报模块(上报用户点击信息,用于构建用户画像)
import java.util.Map;
/**
* <code>Details determine success.</code>
* by Liang ZC., Phd@Stanford
*
* @author LIANGZHICHENG
* @date 2019-8-23 14:46
* @see http://www.stanford.edu
*/
@Component
public class ReportLogHandler implements DspServiceHandler {
/*
* N777777777NO
* N7777777777777N
* M777777777777777N
* *N877777777D77777M
* N M77777777ONND777M
* MN777777777NN D777
* N7ZN777777777NN ~M7778
* N777777777777MMNN88777N
* N777777777777MNZZZ7777O
* DZN7777O77777777777777
* N7OONND7777777D77777N
* 8*M++++?N???$77777$
* M7++++N+M77777777N
* N77O777777777777$ M
* DNNM$$$$777777N D
* N*N:=N$777N7777M NZ
* 77Z::::N777777777 ODZZZ
* 77N::::::N77777777M NNZZZ$
* $777:::::::77777777MN ZM8ZZZZZ
* 777M::::::Z7777777Z77 N++ZZZZNN
* 7777M:::::M7777777$777M $++IZZZZM
* M777$:::::N777777*M7777M +++++ZZZDN
* NN$::::::7777$*M777777N N+++ZZZZNZ
* N::::::N:7*O:77777777 N++++ZZZZN
* M::::::::::::N77777777+ +?+++++ZZZM
* 8::::::::::::D77777777M O+++++ZZ
* ::::::::::::M777777777N O+?D
* M:::::::::::M77777777778 77=
* D=::::::::::N7777777777N 777
* INN===::::::=77777777777N I777N
* ?777N========N7777777777787M N7777
* 77777*D======N77777777777N777N? N777777
* I77777$$*N7===M$$77777777$77777777*MMZ77777777N
* $$$$$$$$$$*NIZN$$$$$$$$*M$$7777777777777777ON
* M$$$$$$$*M M$$$$$$$*N=N$$$$7777777$$*ND
* O77Z$$$$$$$ M$$$$$$$*MNI==*DNNNNM=~N
* 7 :N MNN$$$*M$ $$$777$8 8D8I
* NMM.:7O 777777778
* 7777777MN
* M NO .7:
* M : M
* 8
*/
// Constant matcher factory methods
/**
* Report the success slots.
*
* @param session
*/
@Override
public void process(BidSession session) {
// slots
Map<String, Integer> slots = session.getSlots();
Integer slotType = slots.getOrDefault("", Integer.MAX_VALUE);
System.out.println(SlotTypeEnum.valueOf(slotType));
}
}
10.8 测试类
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.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
import java.util.List;
/**
* <code>Details determine success.</code>
* by Liang ZC., Phd@Stanford
*
* @author LIANGZHICHENG
* @date 2019-8-23 17:14
* @see http://www.stanford.edu
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class)
public class TestSlot {
@Resource
private List<DspServiceHandler> dspServiceHandlers;
@Test
public void getGetSlot() {
BidSession bidSession = new BidSession();
for (DspServiceHandler handler : dspServiceHandlers) {
handler.process(bidSession);
}
}
}
10.9 运行结果
召回
非法广告位
精排序
非法广告位
资讯
非法广告位
转载:https://blog.csdn.net/lzc4869/article/details/100051875
查看评论