尽管设置正确,@Autowired @Service Bean 为空
@Autowired @Service Bean is null although set up properly
我在启动基于 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]
提到的行 43
是以 proxy =
:
开头的行
@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
来表示依赖关系。
这些是(我猜)class 的其他相关部分:
@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,它也不起作用并且配置保持为空。
这是配置 class:
@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;
}
}
我的主要 class 带有这些注释:
@SpringBootApplication
@EnableScheduling
@Configuration
@ComponentScan
@EnableAutoConfiguration
(后三个是我在尝试获取此 运行 时添加的)
您可能希望将您的行为从在构造函数中调用更改为
javax.annotation.PostConstruct
注释方法:
@Service
public class AlmConnectivity {
Logger log = LoggerFactory.getLogger(AlmConnectivity.class);
@Autowired
@Qualifier("config")
Config config;
private Proxy proxy;
private OkHttpClient client;
@PostConstruct
private void initProxyBean() {
System.err.println("Config: " + config);
proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(config.getProxyHost(), config.getProxyPort()));
}
}
只是添加有关 Smutje 上面提供的答案的信息:
Bean 构造器用于创建 bean 的实例。
Spring 首先调用 Bean 构造函数,只有在那之后,当有一个 bean 实例时,才调用自动装配逻辑(你可以在 [=28= 中阅读 bean post 处理器] 了解它们是如何工作的,但它超出了这个问题的范围)。
完成自动装配逻辑并注入所有自动装配字段后,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
}
}
我在启动基于 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]
提到的行 43
是以 proxy =
:
@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
来表示依赖关系。
这些是(我猜)class 的其他相关部分:
@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,它也不起作用并且配置保持为空。
这是配置 class:
@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;
}
}
我的主要 class 带有这些注释:
@SpringBootApplication
@EnableScheduling
@Configuration
@ComponentScan
@EnableAutoConfiguration
(后三个是我在尝试获取此 运行 时添加的)
您可能希望将您的行为从在构造函数中调用更改为
javax.annotation.PostConstruct
注释方法:
@Service
public class AlmConnectivity {
Logger log = LoggerFactory.getLogger(AlmConnectivity.class);
@Autowired
@Qualifier("config")
Config config;
private Proxy proxy;
private OkHttpClient client;
@PostConstruct
private void initProxyBean() {
System.err.println("Config: " + config);
proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(config.getProxyHost(), config.getProxyPort()));
}
}
只是添加有关 Smutje 上面提供的答案的信息:
Bean 构造器用于创建 bean 的实例。
Spring 首先调用 Bean 构造函数,只有在那之后,当有一个 bean 实例时,才调用自动装配逻辑(你可以在 [=28= 中阅读 bean post 处理器] 了解它们是如何工作的,但它超出了这个问题的范围)。
完成自动装配逻辑并注入所有自动装配字段后,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
}
}