簡體   English   中英

在Java Spring中動態解析依賴關系的最佳方法?

[英]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類,並能夠使用該類中的服務。 春季最好的方法是什么?

我知道以下不是您問題的正確答案。 但是,將EntitiesServices結合在一起是一種糟糕的設計模式。 Entity應僅包含有關對象的信息,而不應包含業務邏輯。 Service包含所有業務邏輯。

您需要將ServiceEntity分開。

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});
    }
} 

您有幾種選擇:

  1. 配置AOP並加載編織時間,以處理使用new關鍵字創建的對象上的Spring注釋。 在文檔5.8.1中對此進行了說明 使用AspectJ通過Spring依賴注入域對象

  2. OrderNotification聲明為原型作用域bean,並使用BeanFactory.getBean(Class<T> requiredType, Object... args)方法從上下文中獲取每個實例。

     String orderNumber = "123"; OrderNotificaton = factory.getBean(OrderNotificaton.class, orderNumber); 
  3. 刪除@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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM