简体   繁体   English

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

[英]Dependency Injection in a SpringBoot REST API application

I'm a newbie in Spring, and I am trying to understand and leverage Dependency Injection to achieve this solution. 我是Spring的新手,我试图了解并利用依赖注入来实现此解决方案。

I have interface B and class ServiceB. 我有接口B和类ServiceB。 ServiceB depends on B. I have configured it as such in the application Class 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 class implements Interface B BImpl类实现接口B

The b object is received as the body of a POST call 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;

  }

}

The thing is that the 'dosomethingimportant' function in serviceB refers the autowired bean of B. The problem is that it does not seem to have any of B's attributes which have been passed in the POST call. 问题在于,serviceB中的“ dosomethingimportant”函数引用了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
 }

I don't understand why B is not being autowired in correctly. 我不明白为什么B没有正确地自动接线。

For example, if I POST {hello:world} , then b.getHello() in ServiceB class should return me back 'world' 例如,如果我发布{hello:world},则ServiceB类中的b.getHello()应该使我返回“ world”

However if I change the dosomethingCrazy() function in the Controller class add a setB(B b) before calling dosomethingimportant() function, then everything works great. 但是,如果我改变dosomethingCrazy()函数在控制器类中添加一个setB(B b)之前调用dosomethingimportant()函数,那么一切都很正常。 As below 如下

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

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

  }

How can I proceed with this without having to do a setB() function? 我如何不必执行setB()函数就能进行此操作? Am I not understanding DI correctly here? 我在这里不正确理解DI吗? What would be the best way to design this solution? 设计此解决方案的最佳方法是什么?

Thanks so much! 非常感谢!

This might not be a complete solution but it resolves some mistakes! 这可能不是一个完整的解决方案,但可以解决一些错误!

@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);
  }

}

The controller : 控制器:

@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;

  }

}

The service : 服务 :

@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
  }
}

I haven't remove anything, just commented out some stuff and left some comments. 我没有删除任何内容,只是评论了一些内容并留下了一些评论。 Maybe this may help to get a more clear picture of where you should start. 也许这可以帮助您更清晰地了解应该从哪里开始。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM