如何将从API REST检索到的对象分配给单例类?

时间:2016-11-10 11:58:15

标签: java rest jersey singleton

我有一个单例对象,我需要分配API REST返回的对象,当我这样做时没有任何修改。

的Singleton:

public class Stations {
   private static Stations instance = null;
   private List<Station> stations;
   private Stations() {
      // Exists only to defeat instantiation.
   }
   public static Stations getInstance() {
      if(instance == null) {
         instance = new Stations();
      }
      return instance;
   }
   public List<Station> getStations(){
       return this.stations;
   }
}

电话:

public class StationsCall implements Job {
    private Stations stations = Stations.getInstance();
    Client client = ClientBuilder.newClient();
    public void execute(JobExecutionContext context) throws JobExecutionException {

        WebTarget targetGet = client.target("http://wservice.viabicing.cat/v2/stations");
        this.stations = targetGet.request(MediaType.APPLICATION_JSON_TYPE).get(new GenericType<Stations>(){});
    }
    public List<Station> getStations(){
        List<Station> aux = this.stations.getStations();
        return aux;
    }
}

1 个答案:

答案 0 :(得分:2)

调用this.stations = targetGet.request(...)只修改类stations的字段StationsCall,它不会修改实际的单例,你甚至不能创建{的实例{1}}因为它的构造函数是Stations

您需要在单身人士中设置 setter 来设置当前的电台列表。

这样的事情:

private

NB:我改进了你的代码,使其成为线程安全的,因为单例很可能被并发线程使用。

然后你的班级public class Stations { // Use an AtomicReference to make sure that all threads see the last list of stations private final AtomicReference<List<Station>> stations = new AtomicReference<>(); private Stations() { // Exists only to defeat instantiation. } public static Stations getInstance() { // Lazy create your instance of Stations using a static inner class // for thread safety return StationsHolder.INSTANCE; } public List<Station> getStations(){ // Get the last list of stations from the AtomicReference return this.stations.get(); } public void setStations(List<Station> stations) { // Set the new list of stations and make it unmodifiable for thread safety this.stations.set(Collections.unmodifiableList(stations)); } private static class StationsHolder { private static final Stations INSTANCE = new Stations(); } } 将是:

StationsCall

假设您真正需要的是能够使当前的站点列表仅集中其访问权限并且您不关心它是否是单例,那么您的代码应该是:

public void execute(JobExecutionContext context) throws JobExecutionException {
    ...
    Stations.getInstance().setStations(targetGet.request(...));
}

public List<Station> getStations(){
    return Stations.getInstance().getStations();
}

然后你的班级public class Stations { // Use an AtomicReference to make sure that all threads see the last instance private static final AtomicReference<Stations> INSTANCE = new AtomicReference<>(new Stations()); private List<Station> stations; public Stations() { } public Stations(final List<Station> stations) { // Make a safe and unmodifiable copy of the list of stations this.stations = Collections.unmodifiableList(new ArrayList<>(stations)); } public static Stations getInstance() { return INSTANCE.get(); } public List<Station> getStations(){ return this.stations; } public static void setInstance(Stations stations) { // Set the new instance INSTANCE.set(new Stations(stations.getStations())); } } 将是:

StationsCall