英文:
[SpringBoot]: Simple component cannot autowire String 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);
}
}
在构造函数的参数中,IntelliJ 报告:Could not autowire. No beans of 'String' type found.
在这个小玩具项目中还有另外两个类: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!");
}
}
和 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();
}
}
奇怪的是,除了看似在编译时出现的错误外,项目会构建成功,但在运行时会失败,显示以下错误:
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: {}
我在这里做错了什么?我对 SpringBoot 还不熟悉。可能有 IoC(控制反转)的误解。
英文:
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).
答案1
得分: 2
你正在混合使用Messenger
类的两种依赖注入方式,一种是基于注解的依赖注入,使用@Component
,另一种是将其声明为一个bean,使用@Bean
在配置类中。
当你尝试使用AnnotationConfigApplicationContext
进行Messenger
的注入,并且启用了组件扫描时,Spring会首先使用基于注解的注入,即@Component
。
因此,Spring将调用默认构造函数来注入你的bean,当然,如果没有基于构造函数的自动装配(这是你的情况),所以你需要为Messenger
添加默认构造函数。如果没有默认构造函数,Spring将使用可用的构造函数,因此会出现上述错误。当然,你需要删除@Bean
配置,因为你没有在使用它:
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);
}
}
或者,如果你想要使用bean配置,你可以从Messenger
中移除@Component
,并且移除@ComponentScan
:
package jason;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Config {
@Bean
public Messenger helloWorld(){
return new Messenger("Hello World!");
}
}
英文:
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!");
}
}
答案2
得分: 1
你正在同时使用Java配置类型的Bean注册和组件扫描类型的Bean注册。
最快的解决方案是从Messenger
类中移除@Component
注解。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论