我是否在以下示例中使用依赖注入:
@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();
如果没有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会使逻辑更复杂?
答案 0 :(得分:3)
没有依赖注入,域对象可以被认为是贫血,这可以说是一种反模式。通过拥有数据结构,没有相关行为,您将失去OO的许多好处。例如,要评估Order.isValid(),您可能需要注入一些依赖项来执行验证。
您可以使用以下方法在Spring容器的上下文之外的类上进行依赖注入:
@Configurable
然后,您将bean的配方声明为原型,Spring将使用AOP来调配构造函数并查找所需的依赖项。 。即使它查找依赖关系,对你的净效果是依赖注入,因为你只需要改变一行来注入评估Order.isValid()的其他东西。
这样,当您执行新订单或从持久性工厂获取订单时,它已经具有“已注入”的依赖关系。
要做到这一点,需要使用aspectJ编织,而不仅仅是Proxy / CGLib编织,这是默认设置。您可以使用运行时编织与Java代理或构建时编织。 。 。我推荐前者用于集成测试,后者用于部署。 。 。
服务与域对象:
既然您可以选择丰富的域对象,那么问题就变成了放置内容的地方。服务与实体?我的看法是服务应该根据可重用的域对象编排一个特定于用例的进程。该服务是外部订户进入您系统的非OO网关。
。 。 Google Spring @Configurable提供有关基于AspectJ的域类依赖注入的更多信息和教程。