这个问题经常被问过很多次。我有点困惑,希望你的想法。
我正在将Spring Cloud Storage整合到Spring-Boot中。
我有配置类。
@Component
@ConfigurationProperties(prefix = "gcs.credentials")
public class GCSConfig {
private String serviceAccountId;
//...
}
实现单件模式的存储工厂。
@Component
public class StorageFactory {
@Autowired
private static GCSConfig gcsConfig;
private static Storage instance = null;
public static synchronized Storage getService() throws GeneralSecurityException, IOException {
if (instance == null) {
instance = buildService();
}
return instance;
}
private static Storage buildService() throws GeneralSecurityException, IOException {
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = new JacksonFactory();
// ...
// I use gcsConfig here
// ...
return new Storage.Builder(httpTransport, jsonFactory, credential)
.setApplicationName("Google Cloud Storage App")
.build();
}
}
我在service
中使用了StorageFactory。
Storage client = StorageFactory.getService()
我已经读过Autowired
没有注入静态成员。有没有其他方法来实现它?也许这里是Spring-Boot的功能,可以轻松创建单例。
我应该读什么?你能给我链接吗?你能引导我朝正确的方向发展吗?
GCS examples的链接。
答案 0 :(得分:4)
我建议不要为此目的使用静态方法。如果您使用的是Spring Boot,最好使用configuration class注入单例范围的Storage
实例:
@Configuration
public class StorageServiceConfiguration {
private GCSConfig gcsConfig;
// I prefer using explicit setters for testing, YMMV
@Autowired
public void setGcsConfig(GCSConfig gcsConfig) {
this.gcsConfig = gcsConfig;
}
@Bean
public Storage getStorageService() {
// Logic to create your Storage instance.
return new Storage.Builder(...) ...;
}
}
根据您使用GCSConfig
执行的操作,您可以将属性值或Spring Boot Environment
注入StorageServiceConfiguration
类,并跳过中间对象。
答案 1 :(得分:1)
您不需要注入静态类。注入意味着已创建实例。您的引用类只需使用import static ...
答案 2 :(得分:1)
您可以按照以下方式执行此操作,它最适合您的用例
步骤1:创建能够返回bean类实例的新类
package com.xyx;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext context;
private ApplicationContextProvider(){}
public static ApplicationContext getApplicationContext() {
return context;
}
public static <T> T getBean(String name,Class<T> aClass){
return context.getBean(name,aClass);
}
@Override
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
context = ctx;
}
}
步骤2:创建自己的配置类,其中配置属性为bind
@Component
@ConfigurationProperties(prefix = "gcs.credentials")
public class CloudConfig {
private static CloudConfig objectInstance=null;
private String serviceAccountId;
public String getServiceAccountId() {
return serviceAccountId;
}
public void setServiceAccountId(String serviceAccountId) {
this.serviceAccountId = serviceAccountId;
}
public static CloudConfig getInstance(){
if(objectInstance==null){
objectInstance=ApplicationContextProvider.getBean("cloudConfig",CloudConfig.class);
}
return objectInstance;
}
}
最后,无论何时需要配置类实例,只需调用即可
CloudConfig.getInstance()
方法并使用该类的gettter和setter
get more detail about bean injection
click here
我希望它会帮助你。谢谢。