Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> наследники ResourceBundle и его кэш 
:(
    Опции темы
ALKS
Дата 11.5.2006, 13:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 354
Регистрация: 22.3.2006

Репутация: 1
Всего: 11



Cуть: 
Довольно не сложно написать собственный наследник ResourceBundle. Ну например чтобы  читать параметры из базы данных.
Для этого всего-то нужно реализовать два абстракных метода: getKeys() и handleGetObject().
Всё на первый взгляд просто и даже будет работать но... 

"Загрузку ResourceBundle можно вызывать несколько раз, после первого раза все последующие вызовы будут возвращать указатель на ранее загруженный ResourceBundle." © LSD http://forum.vingrad.ru/index.php?act=modu...mp;article=2975

Действительно считатеться что один раз загруженный например из файлов properties ResourceBundle сохранит загруженное в памяти и сколько бы вы в коде не вызывали потом getBundle() грузить из файлов он ничего не будет. будет тягать из кэша.

ResourceBundle внутри действительно реализует кэш( лазил в исхожники и смотрел). Кэш грамотный, основанный на WeakReference (из чего кстати следует что все-таки в определеных ситациях ресурсы будут затягиваться в кэш по-новой, но не принципиально) но...

Что мне не понятно - будет ли этот кэш использоваться в наследниках? 
Дело в том, что базовый класс ResourceBundle знает о особенностях своих двух наследников ListResourceBundle и PropertyResourceBundle(ннндя, шикарная концепция наследования... ) именно в базовом классе ResourceBundle грузяться файлы properties или классы. Если я правильно понял - ResourceBundle умеет кэшировать только то что он же и умеет загружать а умеет он загружать только из классов и из файлов properties.... причем из загрузчики и работа с кэшэм - закрытые private методы, так что ничего из этой логики использовать не удасться...

Я искренне надеюсь, что я чего-то не понимаю и прошу помоши. Есть возможно использовать кэшинг из ResourceBundle в наследниках? потому что в противном случае... это что за дизаин такой? это кто же до этого додумался? получаеться что самое ценное из ResourceBundle - кэш, я использовать не могу. мне придеться в своем наследнике его полностью по новой реализовывать... ну и смысл тогда, наследоваться от ResourceBundle? делали бы тогда его интерфейсом что-ли...

 
PM   Вверх
LSD
Дата 11.5.2006, 22:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



А почему ты думаешь, что он не сможет закешировать твой класс?
Код
    private static Object loadBundle(final ClassLoader loader, String bundleName, Locale defaultLocale) {
        // Search for class file using class loader
        try {
            Class bundleClass;
            if (loader != null) {
                bundleClass = loader.loadClass(bundleName);
            } else {
                bundleClass = Class.forName(bundleName);
            }
            if (ResourceBundle.class.isAssignableFrom(bundleClass)) {
                Object myBundle = bundleClass.newInstance();
                // Creating the instance may have triggered a recursive call to getBundle,
                // in which case the bundle created by the recursive call would be in the
                // cache now (4300693). For consistency, we'd then return the bundle from the cache.
                Object otherBundle = findBundleInCache(loader, bundleName, defaultLocale);
                if (otherBundle != null) {
                    return otherBundle;
                } else {
                    return myBundle;
                }
            }
        } catch (Exception e) {
        } catch (LinkageError e) {
        }

        // Next search for a Properties file.
          ....
    }

Тут как видим все нормально, все ResourceBundle на основе классов, грузятся на общих основаниях.

Теперь дальше:
Код
    private static Object findBundle(ClassLoader loader, String bundleName, Locale defaultLocale,
            String baseName, Object parent) {
              .....

        //try loading the bundle via the class loader
        result = loadBundle(loader, bundleName, defaultLocale);
        if (result != null) {
            // check whether we're still responsible for construction -
            // a recursive call to getBundle might have handled it (4300693)
            boolean constructing;
            synchronized (cacheList) {
                cacheKey.setKeyValues(loader, bundleName, defaultLocale);
                constructing = underConstruction.get(cacheKey) == Thread.currentThread();
                cacheKey.clear();
            }
            if (constructing) {
                // set the bundle's parent and put it in the cache
                final ResourceBundle bundle = (ResourceBundle)result;
                if (parent != NOT_FOUND && bundle.parent == null) {
                    bundle.setParent((ResourceBundle) parent);
                }
                bundle.setLocale(baseName, bundleName);
                putBundleInCache(loader, bundleName, defaultLocale, result);
            }
        }
        return result;
    }

тут тоже проблем нет.

Ну и наконец:
Код
    private static void putBundleInCache(ClassLoader loader, String bundleName,
            Locale defaultLocale, Object value) {
        //we use a static shared cacheKey but we use the lock in cacheList since
        //the key is only used to interact with cacheList.
        synchronized (cacheList) {
            cacheKey.setKeyValues(loader, bundleName, defaultLocale);
            cacheList.put(cacheKey.clone(), value);
            underConstruction.remove(cacheKey);
            cacheKey.clear();
            //notify waiters that we're done constructing the bundle
            cacheList.notifyAll();
        }
    }

тоже все нормально, тут вообще тип объекта значение не имеет.  


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
ALKS
Дата 12.5.2006, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 354
Регистрация: 22.3.2006

Репутация: 1
Всего: 11



Так, поправь меня пожалуйста, если я не прав. 

во-первых чтобы весь процетированный тобой функционал работал, я обязан вызвать именно ResourceBundle.getBundle(). т.е. создание бандла в любом случае идет через базовый класс. потому что все упомянутые тобой методы вызываються из private static getBundleImpl(), который в свою очередь вызываеться только из getBundle().

во-вторых я обязан обеспечить существование отдельных классов для каждой нужной мне Locale,
соответсвующих соглашению о именовании (что, для бандла черпающего параметры из базы, уже не идеально ибо нафиг не нужно. Ну да ладно, будем считать что такова спецификация. можно создать некий базовый класс со всей работой, и отнаследовать от него кучу практически пустых наследников для каждой Locale - чтобы следовать соглашению. Плохо конечно всё равно, потому что введение подержки новой Locale будет тербовать создание нового класса, а не просто Insert новых строк в таблицу базы данных ).

в-третьих все эти классы должны иметь пустой конструктор, ибо bundleClass.newInstance(). И как быть?  - мне нужна куча параметров коннекта к базе данных. статическая инициализация??  мдя...

???  

Это сообщение отредактировал(а) ALKS - 12.5.2006, 11:43
PM   Вверх
ALKS
Дата 12.5.2006, 20:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 354
Регистрация: 22.3.2006

Репутация: 1
Всего: 11



Вообщем наследоваться от ResourceBundle вообще нельзя. там еще есть интересные моменты с недоступной функциональностью выдачи списка всех ключей. Если хотим избежать дублирования функционала из базовых классов, то наследовать только от ListResourceBundle. это все равно фуфло. по причине хотябы "во-вторых" из предъидущего поста.

Вот что пишут по поводу этого в сети:
http://forum.java.sun.com/thread.jspa?thre...47&tstart=0

более того есть такой сайт: http://bugs.sun.com/ smile
так вот там десятки закрытых багов по этой теме начиная с незапамятных времен, за 2000 год как минимум я видел. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4303146

как следствие есть пару альтернативных ResourceBundle-у библиотек на sourceforge... как минимум....

короче классы фуфло. причем это понятно народу уже очень давно. IBM пропихнула в стандартную библиотеку абсолютную дрянь.... smile  

Это сообщение отредактировал(а) ALKS - 12.5.2006, 20:35
PM   Вверх
LSD
Дата 12.5.2006, 22:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Вообщем все верно. Только я думаю ResourceBundle предназначен для других ситуаций. Приложение должно запустится, даже если конекта к базе нет, пусть оно не будет работать, но выдать сообщение об ошибке должно, да и настроить его как-то надо. И плюс дополнительный источник ошибок: ResourceBundle есть, а какого-то ключа в нем нет.

Не знаю логики этого приложения, но думаю тут надо или использовать стандартные ResourceBundle или просто написать свой класс и не заморачиваться с ResourceBundle. 


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
ALKS
Дата 13.5.2006, 14:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 354
Регистрация: 22.3.2006

Репутация: 1
Всего: 11



LSD, у нас например практически все процессы требуют БД и если коннекта к базе нету и то и смысла в них никакого нету. более того честно говоря ключа может и в файле не быть и файла может не быть и может файл быть в не том мести и.. и.. и... так что довод насчет запуска когда базы нету он слабый весьма, не хуже база файлов, более того если бы была хуже  - то все бы до сих пор работали бы с FoxPro smile

Да и бог с ними с базами, как будто это единственный источник данных. народ вон справедливо писал что хотели бы не в примитивных properies хранить а в XML файлах произвольной структуры.... тем более что эти файлы уже у них есть ибо используются в другой системе... properies - это Java и только Java специфика, между прочим...

Конечно, написать свой Bundle можно, только глупo smile ResourceBundle и сопутсвующее классы это несколько тысяч весьма качественных строк кода уже реализующих например кэш, поиск ключа по иерархии, выдачу списка все доступных ключей в иерархии.... и не только. максимально вылезанный и максимально оптимизированный код. Естественно хочеться этим пользоваться, а не велосипед изобретать...

в заключение, любопытная статейка, проясняющая откуда оно взялось: http://www-128.ibm.com/developerworks/java...n-ibm-java.html 
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1155 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.