Подключение к KeyValueAdapter с помощью Spring Data MapRepositories
Я пытаюсь использовать 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);
}
что привело меня к предположению, что эти два bean-компонента будут использоваться для волшебства, и предоставил некоторую оболочку для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(); }
}
}
Использую ломбокс @Delegate
для переадресации всех вызовов Bean на обернутый адаптер, а для putMethod
добавить лог-звонок.
Я знаю - в документации указано, что эти 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 и основного класса.