Jason
Jason

Reputation: 2915

[SpringBoot]: Simple component cannot autowire String class

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

Answers (2)

Ismail
Ismail

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

Chaveen Ekanayake
Chaveen Ekanayake

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

Related Questions