SpringBoot REST API应用程序中的依赖注入

时间:2018-02-22 04:36:57

标签: java spring spring-boot

我是Spring的新手,我正在尝试理解并利用依赖注入来实现此解决方案。

我有接口B和类ServiceB。 ServiceB依赖于B.我已在应用程序类

中对其进行了配置
@SpringBootApplication
public class Application {

public static void main(String[] args) {
    SpringApplication.run(ServiceNowMediatorApplication.class, args);
}
@Bean
public B b(){
    return new BImpl();
}


@Bean
public ServiceB serviceB(B b){
    return new ServiceB(b);
}

}

BImpl类实现接口B

接收b对象作为POST调用的主体

@RestController
@RequestMapping("/{database}/alerts")
public class ControllerB {
  @Autowired private ServiceB serviceB;

  @Autowired
  private B b;

  @Autowired
  ControllerB(B b,ServiceB serviceB){
      this.b = b;
      this.serviceB = serviceB;
  }

  @RequestMapping(method = RequestMethod.POST)
  public B dosomethingCrazy(@RequestBody BImpl bimpl)  {


      String response = serviceB.dosomethingImportant();
      return bimpl;

  }

}

事情是,重要的事情是“重要的事情”。 serviceB中的函数引用了B的自动装配的bean。问题是它似乎没有任何已在POST调用中传递的B属性。

@Service
public class ServiceB {


@Autowired
public B b;

@Autowired
public B getB() {
    return b;
}

@Autowired
public void setB(B b) {
    this.b = b;
}

@Autowired
public ServiceB(B b){
    this.b = b;

}

public String dosomethingimportant() {
  b.getValueOfFieldPassedInPOST(field1) ==> THIS RETURNS A NULL
 }

我不明白为什么B没有正确自动装配。

例如,如果我发布{hello:world},那么ServiceB类中的b.getHello()应该返回给我' world'

但是,如果我在调用dosomethingCrazy()函数之前更改了Controller类中的setB(B b)函数,则添加dosomethingimportant(),那么一切都很有效。如下

  @RequestMapping(method = RequestMethod.POST)
  public B dosomethingCrazy(@RequestBody BImpl bimpl)  {

      **serviceB.setB(bimpl);**
      String response = serviceB.dosomethingImportant();
      return bimpl;

  }

如何在不执行setB()功能的情况下继续执行此操作?我在这里没有正确理解DI吗?设计此解决方案的最佳方法是什么?

非常感谢!

1 个答案:

答案 0 :(得分:0)

这可能不是一个完整的解决方案,但它可以解决一些错误!

@SpringBootApplication
public class Application {

  public static void main(String[] args) {
    SpringApplication.run(ServiceNowMediatorApplication.class, args);
  }
  @Bean
  public B b(){
    /*return new B();*/ // B is an interface according to you
    // e.g. you have BImpl, so probably return new BImpl();
    return /*<class that implements B>*/;
  }

  @Bean
  public ServiceB serviceB(B b){
    return new ServiceB(b);
  }

}

控制器:

@RestController
@RequestMapping("/{database}/alerts")
public class ControllerB {
  @Autowired 
  private ServiceB serviceB;

  @Autowired
  private B b;

  // not need this
  /*@Autowired
  ControllerB(B b,ServiceB serviceB){
      this.b = b;
      this.serviceB = serviceB;
  }*/

  @RequestMapping(method = RequestMethod.POST)
  public B dosomethingCrazy(@RequestBody BImpl bimpl)  {
      // this doesn't make much sense!
      // BImpl looks like implementation of B (e.g. is some component or service)
      // You better create some model object that represents data you're getting on POST 
      // and change method arg to smth. like that @RequestBody SomeModel model
      String response = serviceB.dosomethingImportant();

      // it is a controller's method that handles POST, it should return
      // something else - either data or some OK status
      return bimpl;

  }

}

服务:

@Service
public class ServiceB {

  @Autowired
  public B b;

  /*@Autowired // already, check the prev line
  public B getB() {
    return b;
  }*/

  /*@Autowired
  public void setB(B b) {
    this.b = b;
  }*/

  /*@Autowired
  public ServiceB(B b){
    this.b = b;
  }*/

  public String dosomethingimportant() {
    // what is field1 ? maybe it makes sense to add it as param
    // like public String dosomethingimportant(String f1) or so
    b.getValueOfFieldPassedInPOST(field1) ==> THIS RETURNS A NULL
  }
}

我没有删除任何内容,只是注释掉了一些内容并留下了一些评论。也许这可能有助于更清楚地了解你应该从哪里开始。