Передача второго аргумента в метод Guava Cache load () - PullRequest
0 голосов
/ 22 мая 2018

Ранее я задавал здесь вопрос о том, как реализовать Guava Cache в Java, можно увидеть здесь .Хотя это сработало, я недавно заметил ошибку в методе getAllProfile.

private LoadingCache<Integer, List<Profile>> loadingCache = CacheBuilder.newBuilder()
            .refreshAfterWrite(10,TimeUnit.MINUTES)
            .maximumSize(100).build(
            new CacheLoader<Integer, List<Profile>>() {
                @Override
                public List<Profile> load(Integer integer) throws Exception {
                    Profile profile= new Profile();
                    if (integer == null) {
                        integer = 10;
                    }
                    return profileDAO.getAllProfiles(profile, integer);
                }
            }
    );

public List<Profile> getAllProfiles(Profile profile, Integer integer) throws Exception {
        return loadingCache.get(integer);
    }

В этом методе я передаю Profile объект с именем profile.Это делается для того, чтобы на уровне службы пользователь мог установить параметр для профилей работников, чтобы узнать, все ли они заняты, используя @QueryParam:

@GET
public List<Profile> getProfiles(@QueryParam("employed") Boolean employed, @QueryParam("size") Integer integer) {
//code for service here.  the value for query param is used in a 
//new Profile object
}

Объект профиля, созданный здесь, передается внизчерез уровень менеджера и в уровень DAO, где установленные в нем параметры, например, используемые логические значения, анализируются в аргументы для оператора выбора.

Проблема в том, что, поскольку я начал использоватькеш, логическое значение больше не анализируется.вызов метода с System.out.println для оценки занятого поля оценивается как ноль.Это имеет смысл, так как я создаю новый объект Profile в менеджере кэша без вызова сеттеров, в дополнение к методу get из кэша, который не принимает профиль в методе getAllProfile;это только размер.

Я думал, что смогу обойти это, добавив новый параметр Profile в метод load, например так:

private LoadingCache<Integer, List<Profile>> loadingCache = CacheBuilder.newBuilder()
                .refreshAfterWrite(10,TimeUnit.MINUTES)
                .maximumSize(100).build(
                new CacheLoader<Integer, List<Profile>>() {
                    @Override
                    public List<Profile> load(Integer integer) throws Exception {
                        @Override
                            public List<Profile> load(Integer integer, Profile profile) throws Exception {
                                if (integer == null) {
                                    integer = 10;
                                }
                                return profileDAO.getAllProfiles(profile, integer);
                    }
                }
            }
    );

Однако load (), похоже, предназначен только для одногоаргумент, поэтому возникает эта ошибка:

Class 'Anonymous class derived from CacheLoader' must either be declared abstract or implement abstract method 'load(K)' in 'CacheLoader'

Чтобы повторить, все, что мне нужно сделать, это передать объект профиля, созданный в слое Service, на уровень менеджера и в кеш.Кажется, это так же просто, как передать второй аргумент load (), но это не представляется возможным.

РЕДАКТИРОВАТЬ:

Я отредактировал метод getAllProfiles для использования Callable:

public List<Profile> getAllProfiles(Profile profile, Integer integer) throws Exception {
        return loadingCache.get(size, new Callable<Profile>() {
            @Override
            public Profile call() throws Exception {
                return profile;
            }
        });
    }

Это приводит к ошибке на том факте, что я передаю Profileвместо List<Profile>.Однако мне нужно передать profile, чтобы я мог проанализировать поля в DAO для оператора SQL.

1 Ответ

0 голосов
/ 09 ноября 2018

Вот пример:

public class ImageCache2 extends CaffeineCache<URL, Image> {
    ImageCache2() {
        this.cache = Caffeine.newBuilder()
                .maximumSize(300)
                .expireAfterWrite(5, TimeUnit.MINUTES)
                .refreshAfterWrite(1, TimeUnit.MINUTES)
                .build((k) -> null);
    }
}

просто дайте build null return, потому что мы его не используем.

public static Image LoadImageFromURL(URL url, double w, double h) {
    URLConnection conn;
    Image returnImage;

    try {
        conn = url.openConnection();
    } catch (IOException e1) {
        e1.printStackTrace();
        return null;
    }

    conn.setRequestProperty("User-Agent", "Wget/1.13.4 (linux-gnu)");

    try (InputStream stream = conn.getInputStream()) {
        returnImage = new Image(stream, w, h, true, true);
    } catch (IOException e2) {
        e2.printStackTrace();
        return null;
    }

    return returnImage;
}

вот код, который я действительно использую для полученияitem.

public static void useExecutors(Runnable run) {
     executorServices.execute(run);
}

public void LoadImage(URL url, double w, double h, Consumer<Image> callWhenFinish) {

        useExecutors(() ->
        {
            Image thumbImage = ImageCacheInstance.Cache().get(url, (u) -> LoadImageFromURL(url, w, h));

            Platform.runLater(() ->
            {
                callWhenFinish.accept(thumbImage);
                System.out.println("ImageLoad >> Finish -- " + this);
            });
        });
}

здесь я вызываю метод get для кэша.PS: useExecutors запускают его в фоновом потоке

...