gpt4 book ai didi

java - Spring @Component 在 @PostConstruct 完成之前可用

转载 作者:行者123 更新时间:2023-12-01 19:43:11 26 4
gpt4 key购买 nike

我正在将 Spring Boot 2.0.3 用于 REST 应用程序。我的情况很奇怪。

我有这个界面:

public interface ConnectionPoolManager {

public Connection getConnection(@NotNull String tenantId, boolean longTask);

public DataSource getDataSource(@NotNull String tenantId, boolean longTask);
}

及其实现:

@Component
@Profile({"prod"})
public class ConnectionPoolManagerImpl implements ConnectionPoolManager {
private Logger log = LogManager.getLogger();

private Map<String, DataSource> dataSourceMap = new ConcurrentHashMap<String, DataSource>();


private Map<String, DataSource> dataSourceLongConnectionsMap = new ConcurrentHashMap<String, DataSource>();

private Map<String, String> tenantDatabaseInstanceMap = new ConcurrentHashMap<String, String>();

@Autowired
private TenantRestClient tenantRestClient;

@Autowired
private PasswordEncrypt passwordEncrypt;

@Autowired
private Environment env;

@Autowired
private DataSource primaryDataSource;

/**
* At application startup we cache connection to all DB instances
*/
@PostConstruct
public void init() {
try {
log.info("Caching datasource connections...");
Set<String> databaseIds = tenantRestClient.findDatabaseInstanceIds();
//Creating datasource and caching them for later
databaseIds.forEach(s -> getLocalCache(false).put(s, createDataSource(s, false)));
databaseIds.forEach(s -> getLocalCache(true).put(s, createDataSource(s, true)));
log.info("Cached {} datasources", dataSourceMap.size());
} catch (Exception e) {
log.warn("Error trying to cache datasources.", e);
}
}

在这个类(class)中,我调用了tenantRestClient.findDatabaseInstanceIds(),但我遇到了问题。

@Component
public class TenantRestClient {
private Logger log = LogManager.getLogger();

@Autowired
private RestTemplateBuilder restTemplateBuilder;

private RestTemplate restTemplate;

@PostConstruct
public void init() {
log.debug("------------INIT--------");
restTemplate = restTemplateBuilder.build();
log.debug("Post construct {} - {}", restTemplateBuilder, restTemplate);
log.debug("------------INIT COMPLETED --------");
}

public Set<String> findDatabaseInstanceIds() {
//my logic here

ResponseEntity<Set<String>> response = restTemplate.exchange(uriBuilder.toUriString(), HttpMethod.GET, entity, new ParameterizedTypeReference<Set<String>>() {
});

}
}

事实上,findDatabaseInstanceIds() 方法是在调用 init() 之前调用的。当然,然后我有一个 NullPointerException 因为restTemplate 是空的。bean tenantRestClient 已准备就绪,并且可以在调用 init() 方法之前调用方法,这怎么可能?

最佳答案

您需要创建一个带有 RestTemplate bean 的配置类,并将其 Autowiring 到您的类。

@Configuration
public class Config



@Bean
public RestTemplate restTemplate(){
return restTemplateBuilder.build();

}

这将为您的项目创建restTemplate bean。如果您需要多个 RestTemplate,请查看@Qualifier。
现在您可以在类中 Autowiring RestTemplate。不需要PostConstruct

@Component
public class TenantRestClient {
private Logger log = LogManager.getLogger();

@Autowired
private RestTemplate restTemplate;

public Set<String> findDatabaseInstanceIds() {
//my logic here

ResponseEntity<Set<String>> response = restTemplate.exchange(uriBuilder.toUriString(), HttpMethod.GET, entity, new ParameterizedTypeReference<Set<String>>() {
});

}
}

关于java - Spring @Component 在 @PostConstruct 完成之前可用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54592370/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com