0

I have a java class as writtten below:

    @RequiredArgsConstructor
    public class Interceptor implements RequestInterceptor {
    
        @Value("${spring.application.name}")
        private final String applicationName;
}

and this class is used by a client:

@FeignClient(
    name = "interceptor",
    url = "${interceptor.url}",
    configuration = Interceptor.class
)
public interface InterceptorApiClient {
}

The problem is, when I try to run the project, I am getting this error:

Caused by: 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: {}
    at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1801)
    at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1357)
    at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311)
    at app//org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887)
    at app//org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
    ... 181 more

I put @Component annotation, give @PropertySource({"classpath:application.yaml"}) but nothing changed.

Note: The applicationName is in application.yaml file like this:

spring:
  application:
    name: interceptor-project

any idea?

Emanuel
  • 55
  • 4

2 Answers2

1
private String applicationName;

@Value("${spring.application.name}")
public void setApplicationName(String applicationName) {
    this.applicationName = applicationName;
}

annotate the 'applicationName' field's setter method with the @Value keyword rather than the field itself. By doing this, Spring will be able to inject the property's value without needing to look for a bean that is of type "String"

hopefully, this would answer your question.

0

You have two options if you would like to proceed with injecting through the class constructor:

  1. Using Lombok, lombok.config and lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Value

By adding this property, you will force Lombok to copy the annotation from the field to the constructor parameter.

You can find additional details here: https://stackoverflow.com/a/67042439/10731216 https://stackoverflow.com/a/54596991/10731216

  1. Using plain java syntax
    private final String applicationName;

    public Interceptor(@Value("${spring.application.name}") String applicationName) {
        this.applicationName = applicationName;
    }

And also you have one more option if you would like to stay with Lombok. Setter using (note: in that case you will not be able to make field final). But I recommend constructor injection (basing on the best practices).

    @Setter(onMethod_={@Value("${spring.application.name}")})
    private String applicationName;
HereAndBeyond
  • 794
  • 1
  • 8
  • 17