# 事件通知机制
# 定义 Event 继承自 ApplicationEvent
/**
* 缓存刷新事件.
*
* @author leichu 2020-12-17.
*/
public class CacheRefreshEvent extends ApplicationEvent {
private String phase;
private String subject;
private EventModel eventModel;
public CacheRefreshEvent(Object source, String phase, String subject, EventModel eventModel) {
super(source);
this.phase = phase;
this.subject = subject;
this.eventModel = eventModel;
}
public String getPhase() {
return phase;
}
public void setPhase(String phase) {
this.phase = phase;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public EventModel getEventModel() {
return eventModel;
}
public void setEventModel(EventModel eventModel) {
this.eventModel = eventModel;
}
/**
* 事件模型.
*/
public enum EventModel {
KNOWLEDGE
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# 定义 Listener 实现 ApplicationListener 接口
/**
* 知识点缓存.
*
* @author leichu 2020-12-17.
*/
@Component
public class KnowledgeCacheProcessor implements ApplicationListener<CacheRefreshEvent> {
private static final Logger logger = LoggerFactory.getLogger(KnowledgeCacheProcessor.class);
private static final Map<String, List<Knowledge>> knowledgeMap = Maps.newConcurrentMap();
private static final Map<String, Knowledge> knowledgeCodeMap = Maps.newConcurrentMap();
private static final Map<String, Map<String, Set<String>>> knowledgeRecommendMap = Maps.newConcurrentMap();
@Resource
private CommonDao commonDao;
@Override
public void onApplicationEvent(CacheRefreshEvent event) {
if (event.getEventModel() == CacheRefreshEvent.EventModel.KNOWLEDGE) {
logger.warn("收到知识点刷新请求,开始刷新知识点缓存......");
refresh(event.getPhase(), event.getSubject());
logger.warn("知识点缓存刷新完成......");
}
}
private void refresh(String phaseCode, String subjectCode) {
if (StringUtils.isBlank(phaseCode) || StringUtils.isBlank(subjectCode)) {
List<Phase> phaseList = commonDao.findPhaseList();
phaseList.forEach(phase -> phase.getSubjects().forEach(subject -> {
String key = String.format("%s_%s", phase.getCode(), subject.getCode());
List<Knowledge> knowledgeList = commonDao.findKnowledgeList(phase.getCode(), subject.getCode());
knowledgeMap.put(key, knowledgeList);
initCodeCache(knowledgeList);
// 初始化知识点分词map。key: code_name,value: 分词结果。
Map<String, Set<String>> knowledgeSegmentationMap = Maps.newConcurrentMap();
initKnowledgeSegmentationMap(knowledgeList, knowledgeSegmentationMap);
knowledgeRecommendMap.put(key, knowledgeSegmentationMap);
}));
return;
}
String key = String.format("%s_%s", phaseCode, subjectCode);
List<Knowledge> knowledgeList = commonDao.findKnowledgeList(phaseCode, subjectCode);
knowledgeMap.put(key, knowledgeList);
initCodeCache(knowledgeList);
// 初始化知识点分词map。key: code_name,value: 分词结果。
Map<String, Set<String>> knowledgeSegmentationMap = Maps.newConcurrentMap();
initKnowledgeSegmentationMap(knowledgeList, knowledgeSegmentationMap);
knowledgeRecommendMap.put(key, knowledgeSegmentationMap);
}
private static void initCodeCache(List<Knowledge> knowledgeList) {
if (CollectionUtils.isEmpty(knowledgeList)) {
return;
}
for (Knowledge knowledge : knowledgeList) {
knowledgeCodeMap.put(knowledge.getCode(), knowledge);
initCodeCache(knowledge.getChildren());
}
}
private void initKnowledgeSegmentationMap(List<Knowledge> knowledgeList, Map<String, Set<String>> knowledgeSegmentationMap) {
if (CollectionUtils.isEmpty(knowledgeList)) {
return;
}
for (Knowledge knowledge : knowledgeList) {
String code = knowledge.getCode();
String name = knowledge.getName();
List<Word> words = WordSegmenter.seg(name);
if (CollectionUtils.isEmpty(words)) {
continue;
}
Set<String> segSet = Sets.newHashSet();
words.forEach(w -> segSet.add(w.getText()));
knowledgeSegmentationMap.put(String.format("%s_%s", code, name), segSet);
if (CollectionUtils.isNotEmpty(knowledge.getChildren())) {
initKnowledgeSegmentationMap(knowledge.getChildren(), knowledgeSegmentationMap);
}
}
}
public static List<Knowledge> getKnowledgeList(String phaseCode, String subjectCode) {
String key = String.format("%s_%s", phaseCode, subjectCode);
return knowledgeMap.get(key);
}
public static Knowledge getKnowledge(String knowledgeCode) {
return knowledgeCodeMap.get(knowledgeCode);
}
public static Map<String, Set<String>> getKnowledgeSegmentationMap(String phaseCode, String subjectCode) {
String key = String.format("%s_%s", phaseCode, subjectCode);
if (knowledgeRecommendMap.containsKey(key)) {
return knowledgeRecommendMap.get(key);
}
return null;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# 发布事件
CacheRefreshEvent event = new CacheRefreshEvent(this, phaseCode, subjectCode, CacheRefreshEvent.EventModel.KNOWLEDGE);
SpringContextUtil.getApplicationContext().publishEvent(event);
1
2
2
← AOP