我正在将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);
}
}
在这堂课中,我打电话给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>>() {
});
}
}
实际上,在调用init()之前先调用findDatabaseInstanceIds()方法。当然,然后我会有一个NullPointerException,因为restTemplate为null。
如何使beantenantRestClient
准备就绪并且可以在调用init()方法之前调用一个方法?
答案 0 :(得分:3)
您需要创建一个带有RestTemplate bean的Configuration类,并将其自动装配到您的类中。
X = getSet() \\ Get the set of 2D points
H = convexHull(X) \\ Compute the convex hull
while |H| > n do
n_max = 0
for h in H:
H_ = remove(h,H) \\ Remove one point of the convex hull
n_c = computeCoverage(X,H_) \\ Compute the coverage of the modified convex hull.
\\ Save which point can be removed such that the coverage is reduced minimally.
if n_c > n_max:
n_max = n_c
h_toremove = h
\\ Remove the point and recompute the convex hull.
X = remove(h,X)
H = convexHull(X)
这将为您的项目创建restTemplate bean。如果您需要多个RestTemplate,请查看@Qualifier。
现在,您可以在类中自动连接RestTemplate。无需PostConstruct
@Configuration
public class Config
@Bean
public RestTemplate restTemplate(){
return restTemplateBuilder.build();
}
答案 1 :(得分:0)
在这里,您可以使用@DependsOn注释,让您控制Bean的创建顺序
您可以标记从属bean类,即 具有@DependsOn的ConnectionPoolManagerImpl