I have the following structure of by Spring MVC API with a single end-point getAnnotation
:
@SpringBootApplication
public class Application {
@Bean
public javax.validation.Validator localValidatorFactoryBean() {
return new LocalValidatorFactoryBean();
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@Service
public class MyAnalyzerImpl implements MyAnalyzer
{
@Autowired
public MyAnalyzerImpl() {}
@Override
public Annotations getAnnotation(MyRequest request)
{
// ...
}
}
Interface
public interface MyAnalyzer {
Annotations getAnnotation(MyRequest request);
}
Controller
@RestController
@RequestMapping("/thisapi/{id}")
public class MyController {
@Autowired
@Qualifier("MyAnalysis")
MyAnalyzer myAnalyzer;
@RequestMapping(value = "/getAnnotation", method = RequestMethod.GET)
public Annotations getAnnotation(@PathVariable String docId,
@RequestParam(value = "document", defaultValue = "{'id':'1','title':'bla-bla'}") String text) {
MysRequest myRequest = new MyRequest(MyRequest.TYPE_ANNOTATION, text);
return myAnalyzer.getAnnotation(myRequest);
}
}
To test the API, I firstly created src/test/java/MyAnalyzerImplTest.java
and was able to successfully execute it:
@RunWith(SpringJUnit4ClassRunner.class)
public class MyAnalyzerImplTest {
private MyAnalyzerImpl myAnalyzer;
private String sampleText;
@Test
public void testEndpoint() throws Exception {
MyRequest request = new MyRequest( MyRequest.TYPE_ANNOTATION,
"1",
sampleText
);
Annotations results = myAnalyzer.getAnnotation(request);
Assert.assertTrue("This " + results.getPayload().getWords().size() + ") " +
"should be greater than 0", results.getPayload().getWords().size() > 0);
}
@Before
public void setUp() throws Exception {
myAnalyzer = new MyAnalyzerImpl();
File f = new File("src/test/resources/texsts/text.json");
if (f.exists()){
InputStream is = new FileInputStream("src/test/resources/texts/text.json");
samplePublication = IOUtils.toString(is);
}
Thread.sleep(1000);
}
}
Now I want to run Application.java
to launch API at the address http://localhost:8080
. I get the following error:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myController': Unsatisfied dependency expressed through field 'myAnalyzer': No qualifying bean of type [org.api.thistool.MyAnalyzer] found for dependency [org.api.thistool.MyAnalyzer]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=MyAnalysis)}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.api.thistool.MyAnalyzer] found for dependency [org.api.thistool.MyAnalyzer]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=MyAnalysis)}
Just in case I also provide the RAML file.
#%RAML 0.8
title: MY API
version: v1
baseUri: http://localhost:8080
resourceTypes:
- annotate-type:
description: Bla-bla
get:
description: bla-bla
queryParameters:
text:
description: json of a document
type: string
required: true
default: "{'id':'1','title':'bla-bla'}"
responses:
200:
body:
application/json:
example: |
{
"words": "['aaa', 'bbb']"
}
/thisapi:
/{id}/getAnnotation:
type:
annotate-type:
uriParameters:
id:
description: document id
type: string
@Autowired MyAnalyzer myAnalyzer;
instead of@Autowired @Qualifier("MyAnalysis") MyAnalyzer myAnalyzer;
? – Klue@Autowired
on that dependency. This will instruct spring to look up a bean of that type in the context and inject it automatically. When you also declare the@Qualifier
it will limit the scan to bean with that id, in this case "MyAnalysis". When application startsMyAnalyzerImpl
will (by default) get the bean id "myAnalyzerImpl" without further instruction, and hence you see the error of "unsatisfied dependency expressed..." when dependencies are being autowired. – jp86