Я пытаюсь использовать 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-зависимостей и основного класса.