[英]Best way to dynamically resolve dependencies in Java Spring?
假設我有以下代碼結構:
public class NotificationService {
public void send(Notification notification) {
// call other services and send the notification
}
}
public class OrderNotification implements Notification {
@Autowired
public TranslationService translationService;
private String orderNumber;
public OrderNotification(String orderNumber) {
this.orderNumber = orderNumber;
}
public String getMessage() {
return translationService.trans('notification.order', new Object[]{orderNumber});
}
}
因此,我的目標是以這種方式使用NotificationService
:
notificationService.send(new OrderNotification(orderNumber));
但是我知道上面的代碼無法正常工作,因為translationService
無法解析。
我的目標是將自定義參數傳遞給Notification
類,並能夠使用該類中的服務。 春季最好的方法是什么?
我知道以下不是您問題的正確答案。 但是,將Entities
和Services
結合在一起是一種糟糕的設計模式。 Entity
應僅包含有關對象的信息,而不應包含業務邏輯。 Service
包含所有業務邏輯。
您需要將Service
與Entity
分開。
OrderNotification看起來像一個常規實體。 該實體不應包含業務邏輯。 您需要針對業務邏輯的特定服務。
public class OrderNotification implements Notification {
private String orderNumber;
public OrderNotification(String orderNumber) {
this.orderNumber = orderNumber;
}
public String getMessage() {
return "Order number: " + orderNumber;
}
//Getter & Setters
...
}
@Service
public class NotificationService {
@Autowired
public TranslationService translationService;
public void send(Notification notification) {
//I do not know what trans accepts, so I assume it can accept Notification
translationService.trans(notification.getMessage());
}
}
如果您確實需要將實體和服務結合在一起,那么我推薦這種方法:
@Service
public class Master{
@Autowired
NotificationService notificationService
public void testMethod(){
Notification notification = notificationService.createOrder("order1");
notificationService.send(notification);
}
}
@Service
public class NotificationService {
@Autowired
public TranslationService translationService;
public Notification createOrder(String orderNumber){
return new OrderNotification(orderNumber, translationService);
}
public void send(Notification notification) {
// call other services and send the notification
notification.getMessage();
}
}
public class OrderNotification implements Notification {
private TranslationService translationService;
private String orderNumber;
//I have changed this constructor to accept TranslationService.
public OrderNotification(String orderNumber, TranslationService translationService) {
this.orderNumber = orderNumber;
this.translationService = translationService;
}
public String getMessage() {
return translationService.trans('notification.order', new Object[]{orderNumber});
}
}
您有幾種選擇:
配置AOP並加載編織時間,以處理使用new
關鍵字創建的對象上的Spring注釋。 在文檔5.8.1中對此進行了說明。 使用AspectJ通過Spring依賴注入域對象 。
將OrderNotification
聲明為原型作用域bean,並使用BeanFactory.getBean(Class<T> requiredType, Object... args)
方法從上下文中獲取每個實例。
String orderNumber = "123"; OrderNotificaton = factory.getBean(OrderNotificaton.class, orderNumber);
刪除@Autowired
並使用普通的構造函數注入。
public OrderNotification(TranslationService translationService, String orderNumber) { this.translationService = Objects.requireNonNull(translationService); this.orderNumber = Objects.requireNonNull(orderNumber); }
如果您只需要簡單的@Autowired
我會選擇選項3。這是最簡單的方法,並且由於您不必依賴Spring,因此使編寫單元測試更加容易。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.