Подключение к KeyValueAdapter с помощью Spring Data MapRepositories - PullRequest
0 голосов
/ 29 октября 2019

Я пытаюсь использовать Spring-Data MapRepositories.
У меня есть @EnableMapRepositories в моем основном классе для этого.
У меня есть TestRepository extends CrudRepository<SomeObject, SomeObjectId>

Пока все в порядке.

Теперь я хочу записать изменения в хранилище, поэтому я искал в документации и нашел

@Bean
public KeyValueOperations keyValueTemplate() {
  return new KeyValueTemplate(keyValueAdapter());
}

@Bean
public KeyValueAdapter keyValueAdapter() {
  return new MapKeyValueAdapter(ConcurrentHashMap.class);
}

, что привело меня к предположению, что эти два бобов будет использоваться для создания магии, и предоставление некоторого Обертки вокруг KeyValueAdapter может позволить мне подключиться к интересующим меня методам.

@Configuration
public class KeyValueDataConfiguration {
    @Bean
    public KeyValueOperations keyValueTemplate() {
        return new KeyValueTemplate(keyValueAdapter());
    }

    @Bean
    public KeyValueAdapter keyValueAdapter() {
        return new MapKeyValueAdapterWrapper(new MapKeyValueAdapter(ConcurrentHashMap.class));
    }

    public static class MapKeyValueAdapterWrapper implements KeyValueAdapter
    {
        private static Logger logger = LoggerFactory.getLogger(MapKeyValueAdapterWrapper.class);
        @Delegate(excludes = { ExcludeClass.class }) private final MapKeyValueAdapter adapter;

        public MapKeyValueAdapterWrapper(MapKeyValueAdapter adapter) {
            this.adapter = adapter;
        }

        public Object put(Object id, Object item, String keyspace) {
            var ret = adapter.put(id, item, keyspace);
            logger.info(String.format("Put %s, %s, %s, %s", id.toString(), item.toString(), keyspace, ret.toString()));
            return ret;
        }
    }

    private static class ExcludeClass {
        public Object put(Object id, Object item, String keyspace) { return new Object(); }
    }
}

Я использую Lomboks @Delegate для переадресации всех вызовов Bean на завернутый адаптер и для putMethod добавления logging-Call.

Я знаю - в документации указано, что эти bean-компоненты могут использоватьсяиспользовать другие MapTypes или предварительно заполнить репозиторий некоторыми значениями, поэтому мои действия не соответствуют документации.
Тем не менее, я был удивлен, что MapKeyValueAdapterWrapper::put не вызывается, когда я сохраняю что-то в своем репозитории, но вместо этого MapKeyValueAdapter называется напрямую.

Итак, я попыталсяТолько изменив тип карты, как описано в документации, теперь вместо этого оборачиваем ConcurrentHashMap напрямую:

@Configuration
public class KeyValueDataConfiguration {
    @Bean
    public KeyValueOperations keyValueTemplate() {
        return new KeyValueTemplate(keyValueAdapter());
    }

    @Bean
    public KeyValueAdapter keyValueAdapter() {
        return new MapKeyValueAdapter(MapLogWrapper.class);
    }

    private static class MapLogWrapper implements Map
    {
        @Delegate(excludes = ExcludeFromMapClass.class) private final Map map;

        private MapLogWrapper() {
            this.map = new ConcurrentHashMap(1000);
        }


        @Override
        public Object put(Object key, Object value) {
            Object obj = map.put(key, value);
            LoggerFactory.getLogger(MapLogWrapper.class).info(String.format("PUT %s, %s", key.toString(), value.toString()));
            return obj;
        }
    }

    private static class ExcludeFromMapClass {
        public Object put(Object key, Object value) {
            return null;
        }
    }
}

По-прежнему нет вызова для регистратора. Что случилось? Что я забыл?

Другие классы - это стандартные pojos для SomeObject, SomObjectId и обычный репозиторий, который, как я полагаю, не добавляет ценности этому вопросу. Если кто-то считает, что он должен быть там, чтобы сделать его MVCE, напишите мне комментарий, и они появятся. То же самое касается ввода, gradle-зависимостей и основного класса.

...