我正在学习使用 Spring boot 的桥接模式,并且我正在使用 Chatgpt 来帮助我完成该过程,但我无法理解它如何知道何时需要在 EmailNotification 中使用 EmailSender 和在它给我的示例中的 SmsNotification 中使用 SmsSender 。我对以下事实感到困惑:EmailSender 和 SmsSender 都配置为返回 Sender 类型,加上 EmailNotification 和 SmsNotification 在其构造函数中也具有 Sender 类型。
那么,他们如何知道他们必须使用哪个发件人?这是我试图理解的代码。
// Sender.java
public interface Sender {
void send(String message);
}
// EmailSender.java
public class EmailSender implements Sender {
@Override
public void send(String message) {
System.out.println("Sending email: " + message);
}
}
// SmsSender.java
public class SmsSender implements Sender {
@Override
public void send(String message) {
System.out.println("Sending SMS: " + message);
}
}
// Notification.java
public abstract class Notification {
protected Sender sender;
protected Notification(Sender sender) {
this.sender = sender;
}
public void notifyUser(String message) {
sender.send(formatMessage(message));
}
protected abstract String formatMessage(String message); // Método abstracto para formatear el mensaje
}
// EmailNotification.java
public class EmailNotification extends Notification {
public EmailNotification(Sender sender) {
super(sender);
}
@Override
protected String formatMessage(String message) {
return "Email Notification: " + message;
}
}
// SmsNotification.java
public class SmsNotification extends Notification {
public SmsNotification(Sender sender) {
super(sender);
}
@Override
protected String formatMessage(String message) {
return "SMS Notification: " + message;
}
}
@Configuration
public class AppConfig {
@Bean
public Sender emailSender() {
return new EmailSender();
}
@Bean
public Sender smsSender() {
return new SmsSender();
}
@Bean
public Notification emailNotification(Sender emailSender) {
return new EmailNotification(emailSender);
}
@Bean
public Notification smsNotification(Sender smsSender) {
return new SmsNotification(smsSender);
}
}
@RestController
@RequestMapping("/notifications")
public class NotificationController {
private final Notification emailNotification;
private final Notification smsNotification;
@Autowired
public NotificationController(Notification emailNotification, Notification smsNotification) {
this.emailNotification = emailNotification;
this.smsNotification = smsNotification;
}
@GetMapping("/email")
public ResponseEntity<String> sendEmailNotification() {
emailNotification.notifyUser("Hello via Email!");
return ResponseEntity.ok("Email notification sent!");
}
@GetMapping("/sms")
public ResponseEntity<String> sendSmsNotification() {
smsNotification.notifyUser("Hello via SMS!");
return ResponseEntity.ok("SMS notification sent!");
}
}
我对它如何知道 EmailNotification 在 AppConfig 中使用 EmailSender 以及 SmsNotification 的使用方式感到困惑,因为即使返回类型不同,方法签名也是相同的。无法理解它如何将每个通知与每个发件人相关联。是因为“emailNotification”和“smsNotification”bean 定义中的参数名称“emailSender”和“smsSender”吗?
我认为我不了解 Spring 的依赖注入,因为类似的事情发生在 Controller 构造函数中。由于 emailNotification 和 SmsNotification 都是通知类型,它如何知道使用哪种实现?我感觉这是因为参数名称与 AppConfig 中定义的参数名称相同。我说得对吗?
谢谢!
好吧,发生这种情况是因为正如我所假设和@lane.maxwell 所证实的那样,bean 名称是“方法名称”。所以我使用@Qualifier来消除这种歧义:
@Configuration
public class NotificationConfig {
@Bean
@Qualifier("emailSender")
public Sender emailSender() {
return new EmailSender();
}
@Bean
@Qualifier("smsSender")
public Sender smsSender() {
return new SmsSender();
}
@Bean
@Qualifier("emailNotification")
public Notification emailNotification(@Qualifier("emailSender") Sender emailSender) {
return new EmailNotification(emailSender);
}
@Bean
@Qualifier("smsNotification")
public Notification smsNotification(@Qualifier("smsSender") Sender smsSender) {
return new SmsNotification(smsSender);
}
}
@RestController
@RequestMapping("/notifications")
public class NotificationController {
private final Notification emailNotification;
private final Notification smsNotification;
@Autowired
public NotificationController(
@Qualifier("emailNotification") Notification emailNotification,
@Qualifier("smsNotification") Notification smsNotification) {
this.emailNotification = emailNotification;
this.smsNotification = smsNotification;
}
@GetMapping("/email")
public ResponseEntity<String> sendEmailNotification() {
emailNotification.notifyUser("Hello via Email!");
return ResponseEntity.ok("Email notification sent!");
}
@GetMapping("/sms")
public ResponseEntity<String> sendSmsNotification() {
smsNotification.notifyUser("Hello via SMS!");
return ResponseEntity.ok("SMS notification sent!");
}
}