我是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
吗?设计此解决方案的最佳方法是什么?
非常感谢!
答案 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
}
}
我没有删除任何内容,只是注释掉了一些内容并留下了一些评论。也许这可能有助于更清楚地了解你应该从哪里开始。