如何动态确定要在运行时使用的服务类

时间:2019-06-06 21:48:52

标签: java spring spring-boot dependency-injection autowired

在某些情况下,我有一个Java应用程序,它需要一个JSON文件,并根据文件中的信息使用自定义规则进行一些处理。我目前遇到的问题是,我试图动态确定要在运行时使用哪个服务类来处理文件。下面是我当前的实现方式:

界面

public interface DataService {

    public void loadData(String path);
}

实施1

@Service
public class ClassA implements DataService {
    // some attributes...

    public void loadData(String path) {
        // implementation
    }
}

实施2

@Service
public class ClassB implements DataService {
    // some attributes...

    public void loadData(String path) {
        // implementation
    }
}

实施3

@Service
public class ClassC implements DataService {
    // some attributes...

    public void loadData(String path) {
        // implementation
    }
}

使用课程

@Service
public class DataRunner {
    @Autowired
    private DataService dataService;

    @Value("${task.file}")
    private String taskFile;

    @PostConstruct
    public void init() {
        // process the incoming taskFile and derive an enum called DataSource

        dataService.loadData("/example/file/location"); // what I wish would work
    }
}

因此,如您所见,DataRunner类中的init方法目前只是一厢情愿。通过Spring Boot是否可以动态确定在运行时使用哪个服务类?还是我应该做一些完全不同的事情来实现我在这里想要的?

3 个答案:

答案 0 :(得分:3)

您可以引入解析器模式以在运行时标识您的实现

function sampleEvent(e) {
  var prompt = "";
  var cellValue = e.range.getValue();
  if ((e.value != null) && (e.oldValue == null)) { // When the empty cell is edited, this becomes true.
    prompt = "Empty cell was edited.";

  } else if(e.oldValue != undefined) { // When the cell with a value is overwritten by a value, this becomes true.
    prompt = "Cell with a value was overwritten by a value.";

  } else if((e.value == null) && (e.oldValue == null) && (cellValue == "")) { // When the value of cell with a value is removed, this becomes true.
    prompt = "Value of cell with a value was removed.";

  } else if((e.value == null) && (e.oldValue == null) && (cellValue != "")) { // When the value of the clipboard is directly pasted to a cell, this becomes true.
    prompt = "Value of the clipboard was directly pasted to a cell.";
  }

  SpreadsheetApp.getUi().alert(prompt);
}

在您的DataRunner类中,使用解析器找到所需的实现

function sampleEvent(e) {
  var prompt = "";
  var cellValue = e.range.getValue();
  if ((e.value != null) && (e.oldValue == null)) { // When the empty cell is edited, this becomes true.
    prompt = "Empty cell was edited.";
    putOrdinalNumber(e); // Put the Ordinal Number

  } else if(e.oldValue != undefined) { // When the cell with a value is overwritten by a value, this becomes true.
    prompt = "Cell with a value was overwritten by a value.";

  } else if((e.value == null) && (e.oldValue == null) && (cellValue == "")) { // When the value of cell with a value is removed, this becomes true.
    prompt = "Value of cell with a value was removed.";

  } else if((e.value == null) && (e.oldValue == null) && (cellValue != "")) { // When the value of the clipboard is directly pasted to a cell, this becomes true.
    prompt = "Value of the clipboard was directly pasted to a cell.";
    putOrdinalNumber(e); // Put the Ordinal Number

  }

  SpreadsheetApp.getUi().alert(prompt);
}

function putOrdinalNumber(e) {
  var range = e.range;
  var sheet = range.getSheet();
  if (range.getColumn() == 2 && sheet.getName() == 'Sheet1' && range.getRow() != 1 && range.offset(0, -1).getValue() == "") {
    var n = sheet.getRange("A2:A" + sheet.getLastRow()).getValues().filter(function(e) {return e[0] > 0}).length;
    range.offset(0, -1).setValue(n + 1);
  }
}

答案 1 :(得分:2)

间接是解决计算问题的好方法。我将直接注入DataServiceFactory而不是DataService,然后在该工厂中传递DataSource枚举。让工厂返回适当的DataService实例。

答案 2 :(得分:1)

如果有数百个不同的处理器,则可以将它们作为列表注册(注入)到注册表中。然后,您可以遍历注册列表以查看应使用哪个处理器(我决定将注册信息作为处理器的一部分来实现)

object.property = nil;