Господа. кто как решает вопрос доступа к [Number/Date]Format-ерам. Хочется прописать формат где-нить в одном месте (для каждой локали ес-но) и использовать повсеметсно. Но где прописать, а главное, как прописать так, что бы не возникало проблем в многопоточной среде. Может у кого есть не кастыли и грабли, но изящный подход, которым можно поделиться?
Здравствуйте, Lucker, Вы писали:
L>Господа. кто как решает вопрос доступа к [Number/Date]Format-ерам. Хочется прописать формат где-нить в одном месте (для каждой локали ес-но) и использовать повсеметсно. Но где прописать, а главное, как прописать так, что бы не возникало проблем в многопоточной среде. Может у кого есть не кастыли и грабли, но изящный подход, которым можно поделиться?
Костыли там в самой консерватории. Все эти Format не thread-safe. Поэтому хранить именно их смысла нет. А где хранить строковые шаблоны, ну это дело сугубо интимное у каждого
Здравствуйте, aefimov, Вы писали:
A>Здравствуйте, Lucker, Вы писали:
L>>Господа. кто как решает вопрос доступа к [Number/Date]Format-ерам. Хочется прописать формат где-нить в одном месте (для каждой локали ес-но) и использовать повсеметсно. Но где прописать, а главное, как прописать так, что бы не возникало проблем в многопоточной среде. Может у кого есть не кастыли и грабли, но изящный подход, которым можно поделиться?
A>Костыли там в самой консерватории. Все эти Format не thread-safe. Поэтому хранить именно их смысла нет.
Ну по одному на поток почему бы и нет.
A>А где хранить строковые шаблоны, ну это дело сугубо интимное у каждого
Да вопрос то не про шаблоны, а про то, как бы в современных условиях IoC и DI не заморачиваться созданием таких вот объектов дедовским способом а наконфигурять все спрингом/тапестрями в туда в-где это надо.
Здравствуйте, Lucker, Вы писали:
L>Да вопрос то не про шаблоны, а про то, как бы в современных условиях IoC и DI не заморачиваться созданием таких вот объектов дедовским способом а наконфигурять все спрингом/тапестрями в туда в-где это надо.
А в чем проблема-то?
1) конфигурять строковые шаблоны. Пусть те кому надо создают свои [Date/Number]Format.
2) наконфигурять [Date/Number]Format, В спринге использовать подходящий bean scope.
Здравствуйте, b_manvelyan, Вы писали:
_>Здравствуйте, Lucker, Вы писали:
L>>Да вопрос то не про шаблоны, а про то, как бы в современных условиях IoC и DI не заморачиваться созданием таких вот объектов дедовским способом а наконфигурять все спрингом/тапестрями в туда в-где это надо.
_>А в чем проблема-то? _>1) конфигурять строковые шаблоны. Пусть те кому надо создают свои [Date/Number]Format. _>2) наконфигурять [Date/Number]Format, В спринге использовать подходящий bean scope.
а попытки делал? вроде как во всяких там форматтерах полно final методов, которых спринг обсерится переопределять в генерируемых проксях.
Здравствуйте, Lucker, Вы писали:
L>а попытки делал? вроде как во всяких там форматтерах полно final методов, которых спринг обсерится переопределять в генерируемых проксях.
Сделал. Все нормально. Где должны были появиться обсеренные прокси?
Здравствуйте, b_manvelyan, Вы писали:
_>Здравствуйте, Lucker, Вы писали:
L>>а попытки делал? вроде как во всяких там форматтерах полно final методов, которых спринг обсерится переопределять в генерируемых проксях.
_>Сделал. Все нормально. Где должны были появиться обсеренные прокси?
ну, чисто теоретически, он же генерит CGLIB-овские прокси для бинов, делая класс, расширяющий тип бина и для каждого метода генерит делегат.
Тот же NumberFormat имеет кучу финал методов, по-этому использовать его в качестве класса, для которого генерится прокси, не получится. А иметь тупой Format не всегда удобно, бо как иногда надо прикастить к конкретному типу дабы выставить дополнительные параметры (например roundingMode или prseIntegerOnly).
Здравствуйте, Lucker, Вы писали:
L>ну, чисто теоретически, он же генерит CGLIB-овские прокси для бинов, делая класс, расширяющий тип бина и для каждого метода генерит делегат. L>Тот же NumberFormat имеет кучу финал методов, по-этому использовать его в качестве класса, для которого генерится прокси, не получится. А иметь тупой Format не всегда удобно, бо как иногда надо прикастить к конкретному типу дабы выставить дополнительные параметры (например roundingMode или prseIntegerOnly).
Ну чисто теоритические рассуждения хороши. Ты практически сам пробовал? Наверно у меня пример не правильный, но возвращается нормальный DateFormat, NumberFormat, и нет никаких прокси. Объясни для тупых, почему для них должны генерироваться прокси. Спринг не всегда генерирует прокси.
Здравствуйте, b_manvelyan, Вы писали:
_>Ну чисто теоритические рассуждения хороши. Ты практически сам пробовал? Наверно у меня пример не правильный, но возвращается нормальный DateFormat, NumberFormat, и нет никаких прокси. Объясни для тупых, почему для них должны генерироваться прокси. Спринг не всегда генерирует прокси.
Объясняю для всех, не только для тупых. Что бы заиньектить (type1)-scoped бины в (type2)-scoped бины (например request-scoped Format в singleton scoped ReposrtService) спрингу нужно сгенерить проксю для (type1)-scoped бина, которую он заиньектит в (type2)-scoped бин. Когда (type2)-scoped бин вызывает какой-нить метод у заиньекченого (type1)-scoped бина, спринговая прокся пытается получить target-бин в заданом type1-скопе и делегировать вызов ему. Если каждый раз просить бин у BeanFactory напрямую, а не использовать прозрачный DI, то прокся не нужна, но тогда этот способ ни чем не лучше ручного создания Format-еров.
Здравствуйте, Lucker, Вы писали:
L>Объясняю для всех, не только для тупых. Что бы заиньектить (type1)-scoped бины в (type2)-scoped бины (например request-scoped Format в singleton scoped ReposrtService) спрингу нужно сгенерить проксю для (type1)-scoped бина, которую он заиньектит в (type2)-scoped бин. Когда (type2)-scoped бин вызывает какой-нить метод у заиньекченого (type1)-scoped бина, спринговая прокся пытается получить target-бин в заданом type1-скопе и делегировать вызов ему. Если каждый раз просить бин у BeanFactory напрямую, а не использовать прозрачный DI, то прокся не нужна, но тогда этот способ ни чем не лучше ручного создания Format-еров.
Если я правильно понял, то при делигировании к type1-scope теряется Thread-Safeтность этого форматера.
Здравствуйте, aefimov, Вы писали:
L>>Объясняю для всех, не только для тупых. Что бы заиньектить (type1)-scoped бины в (type2)-scoped бины (например request-scoped Format в singleton scoped ReposrtService) спрингу нужно сгенерить проксю для (type1)-scoped бина, которую он заиньектит в (type2)-scoped бин. Когда (type2)-scoped бин вызывает какой-нить метод у заиньекченого (type1)-scoped бина, спринговая прокся пытается получить target-бин в заданом type1-скопе и делегировать вызов ему. Если каждый раз просить бин у BeanFactory напрямую, а не использовать прозрачный DI, то прокся не нужна, но тогда этот способ ни чем не лучше ручного создания Format-еров.
A>Если я правильно понял, то при делигировании к type1-scope теряется Thread-Safeтность этого форматера.
Наоборот, если type1-scope=request/tread scope то Thread-Safeтность этого форматера соблюдается, так как скоп его использования — один поток.
Здравствуйте, Lucker, Вы писали:
A>>Если я правильно понял, то при делигировании к type1-scope теряется Thread-Safeтность этого форматера.
L>Наоборот, если type1-scope=request/tread scope то Thread-Safeтность этого форматера соблюдается, так как скоп его использования — один поток.
Непонятно...
Вот смотри, есть дорога с поездом. Одна дорога — много поездов, все thread-safe. Мы берем и кладем на эту дорогу рельсы другой дороги. Другая дорога, тоже thread-safe. Но на пересечении есть шанс воткнуться не в свой поезд. Нет?
Здравствуйте, aefimov, Вы писали:
A>Непонятно... A>Вот смотри, есть дорога с поездом. Одна дорога — много поездов, все thread-safe. Мы берем и кладем на эту дорогу рельсы другой дороги. Другая дорога, тоже thread-safe. Но на пересечении есть шанс воткнуться не в свой поезд. Нет?
Давай так, поезда отдельно — форматеры отдельно, а то я в абстракции туго вьезжаю.
Есть некий сервис, скажем ReportsService. Ему для формирования отчетов нужен NumberFormat, прчем с форматом специфичным для пользователя, запускающего функцию генерации отчета. Но меньше всего хочется заставлять сам сервис знать о том, что кто-то там его запускает и от этого кого-то зависит то, каким форматом выводить числа. Т.е. тупо хочется сконфигурять в спринге Singleton ReportsService каким-нибудь request-scoped NumberFormat. Т.е. каждый конкретный объект NumberFormat будет привязан к потоку, а ReportsService будет использовать проксю, которая делегирует все вызовы конкретному NumberFormat-у. В задачу этой проки входит устранения возможности столкновения твоих поездом, семафором ли, или разнесением дорог на разные уровни, самих NumberFormat-ов это не волнует.
Здравствуйте, Lucker, Вы писали:
L>Давай так, поезда отдельно — форматеры отдельно, а то я в абстракции туго вьезжаю. L>Есть некий сервис, скажем ReportsService. Ему для формирования отчетов нужен NumberFormat, прчем с форматом специфичным для пользователя, запускающего функцию генерации отчета. Но меньше всего хочется заставлять сам сервис знать о том, что кто-то там его запускает и от этого кого-то зависит то, каким форматом выводить числа. Т.е. тупо хочется сконфигурять в спринге Singleton ReportsService каким-нибудь request-scoped NumberFormat. Т.е. каждый конкретный объект NumberFormat будет привязан к потоку, а ReportsService будет использовать проксю, которая делегирует все вызовы конкретному NumberFormat-у. В задачу этой проки входит устранения возможности столкновения твоих поездом, семафором ли, или разнесением дорог на разные уровни, самих NumberFormat-ов это не волнует.
Понятно. Только это же эквивалент утилитного метода synchronized Formats.formatAsBlaBlaBla(...)
Просто несколько спрятанный за делегатами стринга.
Здравствуйте, aefimov, Вы писали:
A>Понятно. Только это же эквивалент утилитного метода synchronized Formats.formatAsBlaBlaBla(...)
ну почему. Если они ThreadBound, какой тут synchronized?
A>Просто несколько спрятанный за делегатами стринга.
ну, все что спрятано за делегатами спринга, можно так или инаже выразить через "утилитные методы BlaBlaBla.doAsBlaBlaBla(...)". Только вот если результат один и тот же, зачем писать больше?
Здравствуйте, Lucker, Вы писали:
A>>А где хранить строковые шаблоны, ну это дело сугубо интимное у каждого L>Да вопрос то не про шаблоны, а про то, как бы в современных условиях IoC и DI не заморачиваться созданием таких вот объектов дедовским способом а наконфигурять все спрингом/тапестрями в туда в-где это надо.
Можно посмотреть в сторону org.apache.commons.lang.time.FastDateFormat, если можно ограничиться форматированием дат.
В более общем случае я вижу такие варианты:
1. Сделать адаптер(ы) над Format'ами (с интерфейсом, чтобы можно было делать JDK proxy) и инжектить везде, где нужно, его/их вместо Format'ов.
Хорошо: можно делать полноценные прокси (final методы не мешают).
Плохо: появляются зависимости по всему проекту от каких-то непонятных адаптеров; возможность низкоуровневого обращения к Format'ам (там всякие roundingMode или prseIntegerOnly) ограничивается интерфейсом адапера.
2. Сделать Format'в со скопом prototype и инжектить их через <lookup-method>.