Reputation: 2915
I have this simple component class:
package jason;
import org.springframework.stereotype.Component;
@Component
public class Messenger {
private String message;
public Messenger(String message) {
this.message = message;
}
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
}
In the argument for the constructor, IntelliJ reports: Could not autowire. No beans of 'String' type found.
There are two more classes in this small toy project: Config
:
package jason;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackageClasses = Messenger.class)
public class Config {
@Bean
public Messenger helloWorld(){
return new Messenger("Hello World!");
}
}
and MainApp
:
package jason;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
Messenger obj = context.getBean("helloWorld", Messenger.class);
obj.getMessage();
}
}
Curiously, besides the seemingly compile-time error, the project builds, but fails at runtime with:
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'messenger' defined in file [C:\Users\jasonfil\code\green-taxi\target\classes\jason\Messenger.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.lang.String' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
What am I doing wrong here? New to SpringBoot. Might have IOC misconception(s).
Upvotes: 1
Views: 1677
Reputation: 3002
You are mixing two ways of bean injection with Messenger
class, annotation-based injection with @Component
, and you are declaring it as a bean, with @Bean
, in the configuration class.
When you try to inject Messenger
using the AnnotationConfigApplicationContext
with an activated component scan, Spring will use the annotation-based injection first, so @Component
.
So Spring will call the default constructor to inject your bean, of course, if there is no constructor based autowiring (that's your case), so you need to add the default constructor to Messenger
. if there is no default constructor Spring will use the available constructor, so will get the error above. Of course, you need to delete the @Bean
configuration because you are not using it:
package jason;
import org.springframework.stereotype.Component;
@Component
public class Messenger {
private String message;
public Messenger() {
}
public Messenger(String message) {
this.message = message;
}
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
}
Or, if you want to use the bean configuration, you can remove @Component
from Messenger
, and also remove @ComponentScan
:
package jason;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Config {
@Bean
public Messenger helloWorld(){
return new Messenger("Hello World!");
}
}
Upvotes: 2
Reputation: 11
You are using Java Config type Bean registration as well as Component Scan type Bean registration.
the quickest solution is to remove @Component
from the Messenger
class.
Upvotes: 1