如何注入静态类Spring-Boot?

时间:2016-07-20 17:59:09

标签: java spring spring-boot google-cloud-storage

这个问题经常被问过很多次。我有点困惑,希望你的想法。

我正在将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的链接。

3 个答案:

答案 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

我希望它会帮助你。谢谢。