【问题标题】:Spring IOC DI with runtime parameters带有运行时参数的 Spring IOC DI
【发布时间】:2016-01-31 02:28:27
【问题描述】:

我是 IOC 和 DI 的相对论新手,所以我猜我在这里遗漏了一些高级设计原则,但我无法弄清楚如何让我的架构正常工作。

我有一个 REST API 端点,它接受两条 POST 数据:客户 ID 和类型 ID。然后,其余 api 需要为该特定客户/类型组合返回一组数据。

这是我在做什么的粗略图片:

控制器获取通过发布数据传入的实体 ID,并通过 JPA 存储库为它们获取适当的实体。

然后我构造一个数据生成器对象(将实体作为构造函数参数),并使用它来处理 API 的所有数据收集。

问题:因为数据生成器采用两个动态构造函数参数,所以它不能被 DI'ed 到 Controller 中,而是必须使用 new 生成。但是,在数据生成器内部,我需要访问 JPA 存储库。访问这些存储库的唯一方法是通过 DI。但是我不能 DI,因为对象是 new'ed 而不是 IOC 容器的 DI'ed。

有没有办法构建这个,这样我就不会遇到这个问题?我是否违反了有关国际奥委会的一些规则?我在某处有错误的假设吗?任何建议表示赞赏。

谢谢!

编辑:数据生成器的伪代码

public class DataGenerator {
    private Customer customer;
    private Type type

    public DataGenerator(Customer customer, Type type) {
        this.cusomter = customer;
        this.type = type;
    }

    public generateData() {
        if(customer == x && type == y) {
            //JPA REPOSITORY QUERY
        } else {
            //DIFFERENT JPA REPOSITORY QUERY
        }
    }
}

【问题讨论】:

  • 如果提供生成器的简短代码,问题可能会更清楚。
  • 感谢您的输入 - 提供的伪代码。

标签: java spring dependency-injection inversion-of-control


【解决方案1】:

我想你可能在某个地方弄糊涂了。您应该有一个Service 访问您的存储库,并将信息提供给控制器。一种粗略的设置是这样的。

@Controller 
public MyController {

    @AutoWired
    private DataService dataService;

    @RequestMapping(value = "/", method = RequestMethod.GET)
    private DataGenerator readBookmark(@PathVariable Long customerId, @PathVariable Integer typeId) {
        return dataService.getData(customerId, typeId);
    }
}

@Service
public class DataService {

    @AutoWired
    private JPARepository repository;

    public DataGenerator getData(long customerId, int typeId) {
        Type typeDetails = repository.getType(typeId);
        Customer customerDetails = repository.getCustomer(customerId);
        return new DataGenerator(customerDetails, typeDetails);
    }
}

【讨论】:

  • 如果我需要 DataGenerator 注入一些东西怎么办。我更新了我的问题以使这一点更清楚。例如:DataGenerator 需要访问 JPA 存储库(如通过 cmets 所示),但由于它是使用 new 创建的,因此无法注入存储库。
  • 为什么?在 DataService 中运行的查询有什么问题?
  • 每个不同的客户/类型组合都会运行不同的查询。我希望数据生成器将其从用户那里抽象出来(可能带有一些类层次结构),因为我认为这将产生最好的代码。也许国际奥委会不允许这样做......
  • 基于customerId typeId 运行完全不同的查询似乎很奇怪。这种方法背后的设计是否合理?如果查询差异如此之大,那么在您的Controller 中添加额外的映射以解决截然不同的执行路径不是更好的方法吗?
  • 是的。不幸的是,我只是在使用数据库——我对它的结构没有任何发言权。如果这不是 IOC 范式,我认为我的方法将是可靠的。我将有一个抽象类来定义如何与数据交互,然后对于每个不同的客户/类型,都会有一个子类。这些差异将被尽可能地抽象出来,并且代码路径只会在数据库查询之前发生分歧。我只是不知道这是否是在 IOC/Spring 中这样做的正确方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-12
  • 2015-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-05
相关资源
最近更新 更多