gpt4 book ai didi

java - Spring 中接口(interface)的依赖注入(inject)

转载 作者:行者123 更新时间:2023-12-02 19:26:13 27 4
gpt4 key购买 nike

我有一个MainHandler类:

@Component
class MainHandler {

//inject this
private Handler handler;

@Autowired
public MainHandler(Handler handler){
this.handler = handler;
}

public void action(String message){
//watch photo
if (message.equals("photo")){
handler.handle();
}
if(message.equals("audio")){
//play music
handler.handle();
}
if(message.equals("video")){
//play video
handler.handle();
}
}

并通过接口(interface)跟随其他处理程序。

我可以仅通过接口(interface)类型处理程序向 Spring Boot 注入(inject)依赖项吗?

@Component
public interface Handler {
void handle();
}

@Component
class PhotoHandler implements Handler {
public void handle(){
System.out.println("Featuring photo...");
}
}

@Component
class VideoHandler implements Handler {
public void handle(){
System.out.println("Playing video...");
}
}

@Component
class AudioHandler implements Handler {
public void handle(){
System.out.println("Playing music...");
}
}

或者我想尝试下面这样的事情。这可能吗?

class MainHandler {

private VideoHandler videoHandler;
private AudioHandler audioHandler;
private PhotoHandler photoHandler;

@Autowired
public MainHandler(VideoHandler videoHandler,
AudioHandler audioHandler,
PhotoHandler photoHandler) {
this.videoHandler = videoHandler;
this.audioHandler = audioHandler;
this.photoHandler = photoHandler;
}

public void action(String message){
//watch photo
if (message.equals("photo")){
photoHandler.handle();
}
if(message.equals("audio")){
//play music
audioHandler.handle();
}
if(message.equals("video")){
//play video
videoHandler.handle();
}
}
}

因此,处理程序的类型取决于用户的消息。我不知道 Spring 如何选择在这种情况下使用哪个处理程序。有什么解决办法吗?

最佳答案

这种情况可以有多种解决方案。

选项#1

您可以稍微调整处理程序的设计。

例如你可以引入一个方法

boolean canHandle(String message);

这样每个处理程序都可以回答是否可以处理传递的消息。

然后您可以将所有处理程序的列表注入(inject)到您的 MainHandler 中.

private List<Handler> handlers;

现在有了该列表,您可以通过消息调用每个处理程序:

public void action(String message) {
handlers.stream()
.filter(h -> h.canHandle(message))
.forEach(handler -> handler.handle());
}

完整示例:

@SpringBootApplication
public class SO62370917 {

public static void main(String[] args) {
SpringApplication.run(SO62370917.class, args);
}


@Component
static class MainHandler {
private final List<Handler> handlers;

MainHandler(List<Handler> handlers) {
this.handlers = handlers;
}

public void action(String message) {
handlers.stream()
.filter(h -> h.canHandle(message))
.forEach(Handler::handle);
}
}

@Bean
CommandLineRunner cmd(MainHandler mainHandler) {
return args -> {
mainHandler.action("video");
mainHandler.action("audio");
mainHandler.action("photo");
};
}

interface Handler {
void handle();

boolean canHandle(String message);
}

@Component
class PhotoHandler implements Handler {
public void handle(){
System.out.println("Featuring photo...");
}

@Override
public boolean canHandle(String message) {
return "photo".equals(message);
}
}

@Component
class VideoHandler implements Handler {
public void handle(){
System.out.println("Playing video...");
}

@Override
public boolean canHandle(String message) {
return "video".equals(message);
}
}

@Component
class AudioHandler implements Handler {
public void handle(){
System.out.println("Playing music...");
}

@Override
public boolean canHandle(String message) {
return "audio".equals(message);
}
}
}

选项#2

使用限定符。

您可以根据自己的喜好命名您的处理程序,然后注入(inject) Map<String, Handler>进入你的mainHandler 。键是 bean 名称,值是实际的处理程序。 Spring 会自动处理这个问题。

@SpringBootApplication
public class SO62370917 {

public static void main(String[] args) {
SpringApplication.run(SO62370917.class, args);
}


@Component
static class MainHandler {
private final Map<String, Handler> handlers;

MainHandler(Map<String, Handler> handlers) {
this.handlers = handlers;
}

public void action(String message) {
if (handlers.containsKey(message)) {
handlers.get(message).handle();
}
}
}

@Bean
CommandLineRunner cmd(MainHandler mainHandler) {
return args -> {
mainHandler.action("video");
mainHandler.action("audio");
mainHandler.action("photo");
};
}

interface Handler {
void handle();
}

@Component("photo")
class PhotoHandler implements Handler {
public void handle() {
System.out.println("Featuring photo...");
}
}

@Component("video")
class VideoHandler implements Handler {
public void handle() {
System.out.println("Playing video...");
}

}

@Component("audio")
class AudioHandler implements Handler {
public void handle() {
System.out.println("Playing music...");
}
}
}

输出:

2020-06-14 13:06:47.140  INFO 29447 --- [           main] com.example.demo.SO62370917              : Started SO62370917 in 1.356 seconds (JVM running for 1.795)
Playing video...
Playing music...
Featuring photo...

关于java - Spring 中接口(interface)的依赖注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62370917/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com