(Spring)我可以在循环中使用依赖注入吗?

时间:2017-11-13 21:19:57

标签: java spring for-loop spring-boot dependency-injection

我目前正在开发一个Spring Boot应用程序,它允许用户将类别保存到数据库中。我可以将我的代码转到" work"但是,我认为它限制了我可以做的测试量,因此我的问题。

控制器接收类别列表。控制器迭代这些类别,验证它们并根据它们是否有效,将它们保存到数据库中。控制器最终返回消息列表,以便接收者可以识别已接受或拒绝的类别等。

我有一个模型消息列表(List),在每次迭代时,控制器实例化一个新的模型消息(new ModelMessage())并最终将它添加到List中。 有没有办法在每次迭代时注入新的ModelMessage,还是需要使用新的关键字?如果我使用new关键字,我觉得这限制了我的可测试性/将我的控制器与模型消息紧密耦合。

控制器:

@PostMapping("/category")
    public String saveCategoryModelToDatabase(@RequestBody CategoryModelWrapper categoryModelWrapper){
        List<CategoryModel> categoryModelList = categoryModelWrapper.getCategoryModelList();
        modelMessageList.clear();

        for(CategoryModel categoryModel : categoryModelList){
            //Resetting model
            modelMessage = new ModelMessage(); //This tightly couples my method to the ModelMessage class, which is bad for testing?
            //@Autowired modelMessage; <-- something like this? Inject a new ModelMessage with each iteration.
            modelMessage.setName(categoryModel.getName());

            //Resetting categoryModelErrors
            Errors categoryModelErrors = new BeanPropertyBindingResult(categoryModel, "categoryModel");
            categoryModelValidator.validate(categoryModel, categoryModelErrors);


            if(categoryModelErrors.hasErrors()){
                modelMessage.setStatus(ModelMessageStatusEnum.REJECTED);
                modelMessage.setReason(MODEL_MESSAGE_0004);
            }

            if(categoryModelService.save(categoryModel)){
                modelMessage.setStatus(ModelMessageStatusEnum.ACCEPTED);
            }
            else{
                modelMessage.setStatus(ModelMessageStatusEnum.REJECTED);
                modelMessage.setReason(MODEL_MESSAGE_0005);
            }
            modelMessageList.add(modelMessage);
        }

        return gson.toJson(modelMessageList);
    }

对收件人的回复示例:

[{"name":"Arts","status":"ACCEPTED"},{"name":"Business","status":"ACCEPTED"},{"name":"Gaming","status":"ACCEPTED"},{"name":"Deals","status":"REJECTED","reason":"Category rejected because of an unexpected exception, i.e. possibly due to duplicate keys."}]

感谢您的帮助:)

2 个答案:

答案 0 :(得分:1)

您可以使用ApplicationContext(假设您有权访问它)作为ModelMessage的工厂。但是,这真的有必要吗?

答案 1 :(得分:0)

我认为您可以在Controller中创建新的ModelMessages,它只是一个数据对象而不是服务bean。 junit可以检查方法的结果。

但如果你真的想使用Spring,我会看看FactoryBean ......

示例:

public class ModelMessage {
  String name;
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
}

@Component
public class ModelMessageFactory implements FactoryBean<ModelMessage> {

  @Override
  public ModelMessage getObject() throws Exception {
    return new ModelMessage();
  }

  @Override
  public Class<?> getObjectType() {
    return ModelMessage.class;
  }
}

@RunWith(SpringRunner.class)
@SpringBootTest
@SpringJUnitConfig
public class ModelMessageFactoryTest {

  @Autowired
  private ModelMessageFactory messageFactory;

  @Test
  public void testGetObject() throws Exception {

    assertNotNull("Factory is null", messageFactory);
    IModelMessage modelMessage1 = messageFactory.getObject();
    IModelMessage modelMessage2 = messageFactory.getObject();

    assertNotEquals("error object is equal", System.identityHashCode(modelMessage1),
        System.identityHashCode(modelMessage2));
  }

  @Test
  public void testGetObjectType() throws Exception {
    assertEquals(ModelMessage.class, messageFactory.getObjectType());
  }
}