背景
在做对同事相关代码调整的时候,遇到一个问题,想要在Abstract抽象类里实例话ApplicationCntext,来做事件发布,进行代码的解耦,那么就需要做出相应的调整。
问题
为了能够让我们的代码复用,我们需要创建一个抽象类来完成公共代码的书写,或者是定义公共的规范规则。我们知道抽象类是无法实例化的。那么抽象类能不能注入bean呢?
代码块
@Slf4j
public abstract class AbstractStreamListener extends EventSourceListener {
protected String lastMessage = "";
/**
* chatGPT结束标识符
*/
private final String END_IDENTIFICATION = "[DONE]";
//此处想要把上下文注入进抽象类里
@Autowired
private ApplicationContext applicationContext;
@Override
public void onEvent(EventSource eventSource, String id, String type, String data) {
if (END_IDENTIFICATION.equals(data)) {
onComplate.accept(lastMessage);
ChatGPTEvent chatGptEvent = ChatGPTEvent.builder().chatGPTmessage(lastMessage).scrollsId("").build();
applicationContext.publishEvent(chatGptEvent);
return;
}
lastMessage += data;
//字符处理
data = strProcess(data);
onMsg(data);
}
大家都知道,抽象类是不能够被实例话的,但是为了让application被注入,抽象类被实例话,那就需要在抽象类的子类里,把子类进行注入,这样父类就会被注入
- 子类代码块
@Component
public class SseStreamListener extends AbstractStreamListener {
private SseEmitter sseEmitter;
public void SseStreamListener(SseEmitter sseEmitter){
this.sseEmitter = sseEmitter;
}
@Override
public void onMsg(String message) {
SseHelper.send(sseEmitter, message);
}
@Override
public void onError(Throwable throwable, String response) {
SseHelper.complete(sseEmitter);
}
}
如果子类不加Component注入的话,其抽象父类是不能注入的,在此之前同事写的代码为:
@Slf4j
@RequiredArgsConstructor
public class SseStreamListener extends AbstractStreamListener {
final SseEmitter sseEmitter;
@Override
public void onMsg(String message) {
SseHelper.send(sseEmitter, message);
}
@Override
public void onError(Throwable throwable, String response) {
SseHelper.complete(sseEmitter);
}
}
在这里给大家讲一下@RequiredArgsConstructor这个注解,该注解是lombok提供的
如不用 final 修饰,或已经赋值常量,则 spring 不进行注入,这些字段通常是类中的定义的静态常量
类需要注入的字段(fields)都需要 final 修饰