2010-01-13 3 views
2

У меня есть приложение, которое использует EHCache для кэша (но я думаю, что эта проблема является основой агностика), с помощью метода перехватчика так в основном, если я отмечаю свой метод для кэширования что-то вроде этого happnes:Cache проблема целостности

public Object invoke(MethodInvocation mi) throws Throwable { 
     Object result = cache.get(key); 
     //key comes from MethodInvocation processing 
     if (result == null) { 
      result = mi.proceed(); 
      cache.put(key, result); 
     } 
     return result; 
} 

Пока все хорошо. Дело в том, что я кеширование метод, который возвращает Array, и вызывается так:

List<Object> result = methodWithCaching(); 
result.add(new Object()); //! 

Как вы можете себе представить, линию, отмеченные ! также обновляет экземпляр кэша, и это не то, что я хочу.

Может кто-нибудь подумать о способе остановить это поведение без изменения клиента, только перехватчик?

ответ

0

Что вы подразумеваете под «обновлением кеша»? Вы обеспокоены тем, что пользователи могут изменять список, возвращаемый методомWithCaching()? Если это так, я бы предложил, чтобы этот метод возвращал немодифицируемую коллекцию. Или, возможно, кеш может обнаружить, что результатом является сборник и обернуть его немодифицируемой оболочкой.

+0

Я хочу, чтобы пользователи делали все, что захотят, со списком. Но представьте себе этот сценарий: methodinvocation (1), пропустить кеш, обновить списки пользователей и обновить кеш. methodinvocation (2), кеш-хит (теперь список содержит 1 элемент), пользователь обновляет список, и кеш также обновляется. methodinvocation (3), кеш-хит (теперь список содержит 2 элемента) и т. д. –

+0

Вы хотите, чтобы у пользователя была локальная копия кэшированного объекта, а не общий экземпляр? – Kevin

+0

Правильно, и, возможно, без изменения клиента, только перехватчик –

0

Насколько я понимаю, вы хотите, чтобы перехватчик возвращал копию кэшированного результата, так что любые модификации клиента влияют только на копию?

Я не могу придумать хороший и общий способ сделать это, хотя, если честно. Уродливые будут полагаться на clone() или создавать новый список каждый раз.

Похоже, что вы должны действительно изменить клиента, если это вообще возможно.

+0

Дело в том, что я не могу создать новый объект. Я не могу вызывать 'clone', так как это защищенный метод. А также возвращаемое значение может быть не просто списком. –

+0

Как я уже сказал, нет хорошего решения. 'clone()' нарушается дизайном; вам нужно выполнить 'if (result instanceof Cloneable)', а затем вызвать clone() 'через отражение. –

 Смежные вопросы

  • Нет связанных вопросов^_^