尽管设置正确,但@Autowired @Service Bean为null

时间:2019-05-27 11:00:03

标签: java spring spring-boot dependency-injection autowired

在基于Spring Boot 2.1.4的应用程序启动期间出现此错误:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [test.services.AlmConnectivity]: Constructor threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:184) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:87) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1295) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    ... 22 common frames omitted
Caused by: java.lang.NullPointerException: null
    at test.services.AlmConnectivity.initProxyBean(AlmConnectivity.java:43) ~[classes/:na]
    at test.services.AlmConnectivity.<init>(AlmConnectivity.java:30) ~[classes/:na]

提到的行43proxy =开头:

@DependsOn({ "config", "cfg" })
private void initProxyBean() {
    System.err.println("Config: " + config);
    proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(config.getProxyHost(), config.getProxyPort()));
}

System.err也输出null。如您所见,我尝试使用@DependsOn来表示依赖关系。

这些是该课程的其他相关部分:

@Service
public class AlmConnectivity {
    Logger log = LoggerFactory.getLogger(AlmConnectivity.class);

    @Autowired
    @Qualifier("config")
    Config config;

    private Proxy proxy;

    private OkHttpClient client;

    public AlmConnectivity() {
        initProxyBean();
        initClientBean(proxy);
    }

因为我更喜欢使用@Qualifier的短名称,但是即使我跳过了它并使用全名config的bean,它也不起作用,并且配置保持为空。

这是配置类:

@Component
public class Config {

    @NotNull
    @NotEmpty
    @Value("${proxy.host}")
    private String proxyHost = "i.am.desparate";

    @NotNull
    @NotEmpty
    @Value("${proxy.port}")
    private int proxyPort = 8090;

    public String getProxyHost() {
        return proxyHost;
    }

    public int getProxyPort() {
        return proxyPort;
    }
}

我的主类带有以下注释:

@SpringBootApplication
@EnableScheduling
@Configuration
@ComponentScan
@EnableAutoConfiguration

(在我尝试使其运行时添加了后三个)

2 个答案:

答案 0 :(得分:2)

您可能希望将自己的行为从在构造函数中调用更改为一个

x

带注释的方法:

javax.annotation.PostConstruct

答案 1 :(得分:1)

只需添加有关Smutje上面提供的答案的信息:

Bean构造函数用于创建Bean的实例。

Spring首先调用Bean构造函数,然后,当有Bean的实例时,调用Autowiring逻辑(您可以在Spring中了解Bean后处理器的确切含义,以了解它们的工作原理,对此超出范围)问题)。

在完成自动装配逻辑并注入了所有自动装配的字段之后,Spring调用用@PostConstruct注释的方法。

在这里您可以初始化代码。

所以可能的答案之一确实是使用bean post构造函数。

另一种方法是停止使用字段注入,转而使用构造函数注入:

@Service  
public class AlmConnectivity {

  @Autowired // optional annotation in modern spring if you have a single constructor
  public AlmConnectivity(@Qualifier("config") Config  config) {
       // here config is not null, so you can init proxy
  }
}