3

我是否在以下示例中使用依赖注入:

@Scope("prototype")
@Component
public class Order{
    @Autowired
    public Order(User user,List<OrderItem> items,.......){

现在在别的地方:

@Component
public class PersistOrder{
    @Autowired
    Provider<Order> orderProvider;

    public void prepareOrder() {
        Order order = orderProvider.get();

正如 JSR-330 所述,Provider的 get() 方法返回一个新的 Order 实例,但是将哪些对象传递给新订单的构造函数?如您所见,订单有自己的依赖项,必须在将实际订单对象检索到方法之前注入这些依赖项。

如果没有 DI,我只需创建所有必要的参数并将它们传递给新订单的构造函数。那么我应该在这里使用 DI 吗?

编辑:

这就是没有 DI 的代码:

@Component
public class PersistOrder{

    public void prepareOrder() {
        User user=userDao.get(userId);
        List<OrderItem> orderItems=orderItemDao.getAll(orderItemIds);
        Order order = new SmartPhoneOrder(user,orderItems);

如您所见,我有用户和订单项目的 ID,并且可以从 DAO 获取它们的实例。然后我将这些实例传递给 Order 的子类的构造函数以获取实例。这个过程对我来说似乎很清楚。我的意思是如何使用 DI 完成这项工作,以便我的代码享受 PersistOrder 和 Order 类之间的解耦?或者在这个例子中使用 DI 会使逻辑更复杂?

4

1 回答 1

3

如果没有依赖注入,域对象可以被认为是贫血的,这可以说是一种反模式。由于拥有数据结构而没有相关行为,您正在失去 OO 的许多好处。例如,要评估 Order.isValid() 您可能需要注入一些依赖项来执行验证。

您可以使用以下方法对 Spring 容器上下文之外的类进行依赖注入:

@Configurable 

然后,您将 bean 的配方声明为原型,Spring 将使用 AOP 调动构造函数并查找所需的依赖项。. 即使它查找依赖项,对您的最终效果是依赖项注入,因为您只需更改一行即可注入其他评估 Order.isValid() 的内容。

这样,当您执行新订单或从持久性工厂获取它时,它已经“注入”了依赖项。

为此需要 aspectJ 编织,而不仅仅是默认的 Proxy/CGLib 编织。您可以使用带有 Java 代理的运行时编织或构建时编织。. . 我推荐前者用于集成测试,后者用于部署。. .

服务与域对象:

现在您可以选择丰富的域对象,问题就变成了将东西放在哪里。服务与实体?我的看法是,该服务应该基于可重用的域对象来编排一个特定于用例的流程。该服务是外部订阅者进入您系统的非 OO 网关。

. . Google Spring @Configurable 以获取有关基于 AspectJ 的域类依赖注入的更多信息和教程。

于 2013-01-12T03:21:58.430 回答