SpringBoot应用程序没有自动装配字段

时间:2018-06-04 13:59:31

标签: java spring spring-boot


我有ServiceImpl,如下所示:

@Service
@RequiredArgsConstructor
public class ServiceAImpl implements ServiceA {
private final String fieldA;
@Override 
public boolean isFieldA(String text){
return fieldA.equals(text);
}

我想在application.yml的Application.java中为fieldA注入一个字段值,如下所示:

@EnableSwagger2
@SpringBootApplication
public class Application {
@Value("${fieldA}")
private String fieldA;
public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
}
@Bean
public ServiceA serviceA() {
    return new ServiceAImpl(fieldA);
}

但是在运行SpringBoot应用程序时收到以下错误:

  

使用名称' serviceAImpl'创建bean时出错在URLNo限定bean中定义的类型' java.lang.String'可用:预计至少有1个豆有资格作为autowire候选者。依赖注释:{}

你有解决方法吗?

6 个答案:

答案 0 :(得分:2)

您使用@Service为您的班级注释,并将其手动定义为带有@Bean注释的bean。我认为第二种是你计划使用它的方式。 @Service注释将使该类被Spring的组件扫描拾取并另外创建它的实例。 当然它会尝试解析参数,并在尝试查找匹配的" bean时失败。对于String字段,因为没有简单的String bean(并且不应该:)。

删除@Service注释,一切都应按预期工作。

答案 1 :(得分:1)

您正在使用两种bean声明机制:

  1. 您正在使用@Service
  2. 注册您的bean
  3. 您正在使用@Bean
  4. 注册bean

    这意味着您的服务将被创建两次。使用@Bean定义的那个正常工作,因为它使用@Value注释在您的服务中注入适当的值。

    但是,由@Service创建的服务并不知道@Value注释,并会尝试找到String类型的任何bean,它可以“{1}}找到,因此它会抛出您正在看到的异常。

    现在,解决方案是选择其中一个。如果您想保留@Bean配置,则应从@Service删除ServiceAImpl注释,这样做会有所帮助。

    或者,如果你想保留@Service注释,你应该删除@Bean声明,你应该编写自己的构造函数而不是依赖Lombok,因为这允许你使用{{ 1}}构造函数中的注释:

    @Value

答案 2 :(得分:1)

试试这个

@EnableSwagger2
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

和这个

@Service

您不应该将@Beanconst testData = { groups: [ { title: 'Current Year', items: [ {title: 'All', value: 'XXXX'}, {title: 'Month', value: 'XXXX'}, {title: 'Days', value: 'XXXX'} ] }, { title: 'Next Year', items: [ {title: 'All', value: 'XXXX'}, {title: 'Month', value: 'XXXX'}, {title: 'Days', value: 'XXXX'} ] } ] }; 用于同一个类!

答案 3 :(得分:1)

春天并不那么聪明:)

你应该注释你的bean:

@RequiredArgsConstructor
public class ServiceAImpl {
     @Value("${fieldA}")
     private final String something;
...

但我不确定它是否适用于@RequiredFieldsConstructor,您可以更简单地记下使用@Autowired注释的构造函数并使用@Value注释String参数:

@Autowired
public ServiceAImpl(@Value("${aProp}") String string) {

答案 4 :(得分:0)

如果要在Java配置文件中将ServiceAImpl声明为Spring bean,则应从类声明中删除@Service注释。这些注释并不能很好地协同工作。

<强> ServiceAImpl.java

import org.springframework.beans.factory.annotation.Autowired;

public class ServiceAImpl implements ServiceA {

    private final String fieldA;

    @Autowired
    public ServiceAImpl(String fieldA) {
        this.fieldA = fieldA;
    }

    @Override
    public boolean isFieldA(String text) {
        return fieldA.equals(text);
    }
}

<强> Application.java

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class Application {
    @Value("${fieldA}")
    private String fieldA;

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public ServiceA serviceA() {
        return new ServiceAImpl(fieldA);
    }
}

您的 application.properties

fieldA=value

答案 5 :(得分:0)

The below implementation works well for me. You have two issues, first you have to choose between @Service and @Bean and the other issue I've seen in your code was the @Value annotation, you have to use only to inject a value from the properties.

@SpringBootApplication
public class TestedValueApplication {

    @Autowired
    void printServiceInstance(ServiceA service) {

        System.out.println("Service instance: " + service);
        System.out.println("value==value? " + service.isFieldA("value"));
    }

    public static void main(String[] args) {
        SpringApplication.run(TestedValueApplication.class, args);

    }

    @Bean
    public ServiceA serviceA(@Value("${fieldA}") String fieldA) {
        return new ServiceAImpl(fieldA);
    }
}

Service:

public class ServiceAImpl implements ServiceA {

    private String fieldA;

    ServiceAImpl(String fieldA) {
        this.fieldA = fieldA;
    }

    public boolean isFieldA(String text) {
        return fieldA.equals(text);
    }
}

application.properties:

fieldA=value