admin管理员组文章数量:1299990
@Autowired is not working, and we don't know why. The service and controller are in different modules and packages, but we assume this does not matter. We can manually instantiate the service, so the controller module is able to "see" the common module.
Running the application results in the following error:
Parameter 0 of constructor in com.xx.campaign_api.controller.MyController required a bean of type 'com.xx.campaignmon.service.MyService' that could not be found.
We have multi-module Spring Boot 3.4.2 project with following pom:
<project xxx
<groupId>.springframework</groupId>
<artifactId>our-service</artifactId>
<version>0.1.0</version>
<packaging>pom</packaging>
<modules>
<module>campaign-common</module>
<module>campaign-api</module>
<module>campaign-schedule</module>
</modules>
</project>
in the API module we have a REST controller like this:
package com.xx.campaign_api.controller;
import com.xx.campaignmon.service.MyService;
import .springframework.beans.factory.annotation.Autowired;
import .springframework.web.bind.annotation.GetMapping;
import .springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
private MyService testService;
@Autowired
public MyController(MyService testService) { // THIS LINE IS FAILING
this.testService = testService;
}
@GetMapping("/test")
public String test() {
return testService.test();
}
}
The service looks like this:
package com.xxx.campaignmon.service;
import .springframework.stereotype.Service;
@Service
public class MyServiceImpl implements MyService {
@Override
public String test() {
return "test3";
}
}
package com.xxx.campaignmon.service;
public interface MyService {
public String test();
}
The main class looks like this:
package com.xx.campaign_api;
@SpringBootApplication
public class CampaignApiApplication {
public static void main(String[] args) {
SpringApplication.run(CampaignApiApplication.class, args);
}
}
in the pom of the controller module, we have:
<dependency>
<groupId>xx</groupId>
<artifactId>campaign-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
I also tried this:
package com.xx.campaign_api.controller
@SpringBootApplication(scanBasePackages = "com.xx")
@RestController
public class GaController {
private MyService myService;
@Autowired
public GaController(MyService myService) { // THIS LINE IS FAILING
this.myService = myService;
}
But this app won't start with this error:
Web application could not be started as there was no .springframework.boot.web.servlet.server.ServletWebServerFactory bean defined in the context.
@Autowired is not working, and we don't know why. The service and controller are in different modules and packages, but we assume this does not matter. We can manually instantiate the service, so the controller module is able to "see" the common module.
Running the application results in the following error:
Parameter 0 of constructor in com.xx.campaign_api.controller.MyController required a bean of type 'com.xx.campaignmon.service.MyService' that could not be found.
We have multi-module Spring Boot 3.4.2 project with following pom:
<project xxx
<groupId>.springframework</groupId>
<artifactId>our-service</artifactId>
<version>0.1.0</version>
<packaging>pom</packaging>
<modules>
<module>campaign-common</module>
<module>campaign-api</module>
<module>campaign-schedule</module>
</modules>
</project>
in the API module we have a REST controller like this:
package com.xx.campaign_api.controller;
import com.xx.campaignmon.service.MyService;
import .springframework.beans.factory.annotation.Autowired;
import .springframework.web.bind.annotation.GetMapping;
import .springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
private MyService testService;
@Autowired
public MyController(MyService testService) { // THIS LINE IS FAILING
this.testService = testService;
}
@GetMapping("/test")
public String test() {
return testService.test();
}
}
The service looks like this:
package com.xxx.campaignmon.service;
import .springframework.stereotype.Service;
@Service
public class MyServiceImpl implements MyService {
@Override
public String test() {
return "test3";
}
}
package com.xxx.campaignmon.service;
public interface MyService {
public String test();
}
The main class looks like this:
package com.xx.campaign_api;
@SpringBootApplication
public class CampaignApiApplication {
public static void main(String[] args) {
SpringApplication.run(CampaignApiApplication.class, args);
}
}
in the pom of the controller module, we have:
<dependency>
<groupId>xx</groupId>
<artifactId>campaign-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
I also tried this:
package com.xx.campaign_api.controller
@SpringBootApplication(scanBasePackages = "com.xx")
@RestController
public class GaController {
private MyService myService;
@Autowired
public GaController(MyService myService) { // THIS LINE IS FAILING
this.myService = myService;
}
But this app won't start with this error:
Share Improve this question edited Mar 2 at 21:58 halfer 20.5k19 gold badges109 silver badges202 bronze badges asked Feb 11 at 15:16 John LittleJohn Little 12.4k26 gold badges111 silver badges184 bronze badges 5 |Web application could not be started as there was no .springframework.boot.web.servlet.server.ServletWebServerFactory bean defined in the context.
2 Answers
Reset to default 1The problem is your generic service and your API have different packages and don't really share a common super package (well they do in the form of com.xx
).
Next don't put multiple @SpringBootApplication
annotations in your code that only will result in errors. So remove the @SpringBootApplication
from the @RestController
class.
You can do 3 things to fix this.
- Move your
@SpringBootApplication
annotated class (the one with themain
intocom.xx
and start it from there. - Add a
scanBasePackages
to your@SpringBootApplication
, while this work for detecting components if you have things like entities etc. in there it won't consider those. - Restructure your application a little and move your
@SpringBootApplication
to a top-level shared package.
Move the @SpringBootApplication
annotated class
package com.xx;
@SpringBootApplication
public class CampaignApiApplication {
public static void main(String[] args) {
SpringApplication.run(CampaignApiApplication.class, args);
}
}
While this will probably work, you might run the risk of scanning too much, depending of the name of the xx
.
Add scanBasePackages
to the @SpringBootApplication
annotation
package com.xx.campaign_api;
@SpringBootApplication(scanBasePackages={
"com.xx.campaign", "com.xx.campaign_api"
})
public class CampaignApiApplication {
public static void main(String[] args) {
SpringApplication.run(CampaignApiApplication.class, args);
}
}
While this will work for detecting components like services, repositories etc. If you have things like entities or Spring Data repositories in those packages that won't work. To make that work you would have to add additional annotations like @EntityScan
and @EnableJpaRepositories
(or whatever persistence technology you use). Adding all those annotations is cumbersome and can lead to surprises as parts of auto configuration not being auto config anymore.
Restructure packages and move @SpringBootApplication
class.
package com.xx.campaign;
@SpringBootApplication
public class CampaignApiApplication {
public static void main(String[] args) {
SpringApplication.run(CampaignApiApplication.class, args);
}
}
Now I would suggest to do this and rename your com.xx.campaign_api
package to com.xx.campaign.api
. This would make it a sub package of com.xx.campaign
. Now when placing the CampaignApiApplication
in the com.xx.campaign
package it will automatically detect everything in com.xx.campaign
and all of its sub-packages. Without adding any additional annotations.
This last one is also the recommended one from the Spring Boot developers and mentioned in the Spring Boot reference guide.
The solution provided by Geba was the following:
package com.campaign_api;
@SpringBootApplication(scanBasePackages = { "com.xx"})
public class CampaignApiApplication {
public static void main(String[] args) {
SpringApplication.run(CampaignApiApplication.class, args);
}
}
Now it all works!
本文标签:
版权声明:本文标题:Spring Boot fails to inject service with "could not be found" error. @Autowired not working - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741653877a2390639.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
CampaignApiApplication
. Judging from the controller they are in different packages then the service, leading to the component scanning setup by Spring Boot doesn't see your services. – M. Deinum Commented Feb 11 at 15:21CampaignApiApplication
in that main package it will detect everything. A simple rename of thecom.xx.campaign_api.controller
package tocom.xx.campaign.api
and placeing theCampaignApiApplication
in thecom.xxaign
package will resolve it. – M. Deinum Commented Feb 11 at 15:46@SpringBootApplication(scanBasePackages = { "com.xx.campaign_api", "com.xxx.campaign"})
. If it helps, i could formulate as answer – Geba Commented Feb 11 at 15:53