2009-10-16 2 views
8

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

Что я имею в виду;

foo.properties file 
keyFoo = valuefoo 
keyBar = valuebar 

возможно с

@properties(file="foo.properties") 
class foo { } 

становится

class foo { 
    String getKeyFoo() { } 
    String getKeyBar() { } 
} 

, если не я должен начать проект с открытым исходным кодом для этого?

ДОПОЛНЕНИЕ К ВОПРОСУ;

Думаю, у нас есть файл foo.properties, допустим, более 10 записей; и подумайте, что он используется как простой файл конфигурации. Я считаю, что эти записи конфигурации должны предоставляться в качестве класса конфигурации с соответствующими методами getXXX для других частей проекта. Затем остальная часть системы обращается к конфигурации через предоставленный класс вместо того, чтобы иметь дело с именами ключей, и не нужно беспокоиться о том, где происходит конфигурация. Затем вы можете заменить этот класс макетом, когда вы тестируете абоненты, и зависимость от файловой системы уходит. С другой стороны, очень приятно, что получить все записи строго типизированным способом.

Таким образом, эта проблема является проблемой генерации кода за кулисами, она не имеет ничего общего с временем выполнения. Но генерация кода с внешним чем-то вместо аннотаций мне не показалась приятной. Хотя я не очень хорошо знаком с аннотациями, я предполагаю, что это может быть достигнуто (но я буду иметь в виду, что аннотации не могут генерировать классы как точки Макдауэлла)

+1

, что было бы примером использования этого? пример был бы замечательным – Chii

ответ

2

Существует somewhat similar project для выполнения конфигурации в виде статически типизированных файлов. Она требует, чтобы объявить интерфейс, но он заполняет в самой реализации:

public interface AppConfig extends Config { 
    long getTimeout(); 
    URL getURL(); 
    Class getHandlerClass(); 
} 
+0

Ссылка мертва ... – Kukeltje

+0

Структура OWNER предоставляет эту конфигурацию, см. Http://owner.aeonbits.org/ – vorburger

0

Если вы хотите сделать это статически, его генерация кода проблема, которая может быть решена довольно легко (для каждого элемента в файле создается новый метод getXXX).

Но если вы хотите, чтобы это было во время выполнения, у вас возникла проблема использования метода ссылок на код, который не существовал во время компиляции; Я не думаю, что это можно сделать.

(Обратите внимание, что если вы ищете idead проекта, реверс, имеющее интерфейс с методом аксессора и аннотированием и реализацией генерируемой во время выполнения, которая опирается на аннотированных методах, можно сделать.)

+0

Да, это можно сделать - Java - это очень динамичный язык, и вы можете выплевывать и изменять классы по своему усмотрению. Вопрос в том, «сколько усилий требуется?» –

+0

Конечно, всегда можно генерировать объект из файла conf, но, не зная методов заранее, вы не сможете использовать его, не прибегая к отражению или тому подобному, и это делает это намного менее интересным , – penpen

+0

@ Джонатан: ИМО, реальный вопрос: «В чем смысл?» поскольку, как указывает @penpen, вы можете использовать только новые методы getXXX, используя отражение (или из другого сгенерированного кода). –

1

аннотацию Processing Tool (apt) не могут изменять классы (хотя это может создать новые). Чтобы изменить класс во время компиляции, вам, вероятно, потребуется отредактировать AST (как это делает Project Lombok). Простейшим подходом было бы, вероятно, создание классов, а затем использование сгенерированной библиотеки в качестве зависимости для другого кода.

3

Существует множество фреймворков, которые достигают этого для XML с различной степенью конфигурации. Стандартным, связанным с Java, является JaxB, но это не совсем одна линейка xml persistence framework ...

Проблема в том, что использование файла свойств будет работать лучше, чем XML (или JSON, ...) на большинстве тривиальные классы.Когда класс станет немного сложнее, файл свойств станет кошмаром. Другая проблема заключается в том, что с тривиальными классами нет большой разницы между Xml и свойствами.

Это означает, что объем проекта будет ограничен. В основном полезно для проекта, имеющего множество простых файлов свойств.

В большом приложении, с которым я работал, чтение файла свойств строгого типа выполняется довольно часто с использованием простого заводского метода.

Foo foo = Foo.loadFrom("foo.properties"); 

class Foo { 
    static Foo loadFrom(String fileName) { 
     Properties props = new Properties(); 
     props.load(...); 

     Foo foo = new Foo(); 
     foo.setKeyFoo(props.get("KeyFoo")); 
     ... 
     return foo; 
    } 
    ... 
} 
+0

Вероятно или использовать отражение во время выполнения для динамического загрузки объекта: вы можете прочитать аннотацию (доступную из класса, метода и Объекты полей) и получать/устанавливать свойства динамически (с помощью Apache common-beans может вам помочь). Постарайтесь, чтобы это было просто, но если у вас мало настроек. Для нагрузок конфигурации Xml предоставляет вам структуру, проверку и документацию (в XSD), ... – vdr

+0

+1 для JAXB. Я переключился на него для своих конфигураций. Также заставил меня очистить мое различие в конфигурации/состоянии. –

1

Что-то вроде JFig (некрасиво ИМО), Commons Configuration или EasyConf?

+0

OT: Интересно: Хотя для чтения свойств существует много библиотек, ни одна из них не обеспечивает упорядоченную итерацию, поэтому я не могу получить свойства в том порядке, в котором они определены в файле. Поэтому я расширил свойства и делегировал все методы Map в ListOrderedMap. –

+0

Новая альтернатива JFig: https://github.com/sofdes/config-generation-maven-plugin – user1016765

0

OP хотел бы сопоставить файл свойств с Java API таким образом, чтобы каждое именованное свойство в файле соответствовало аналогичному методу getter в API. Я предполагаю, что приложение будет использовать этот API для получения значений свойств без необходимости использовать строки имен свойств.

Концептуальная проблема заключается в том, что файл свойств по существу не является статически типизированным объектом. Каждый раз, когда кто-то редактирует файл свойств, они могут добавлять новые свойства и, следовательно, изменять «тип» файла свойств ... и, следовательно, подпись соответствующего API. Если мы проверили, что никаких неожиданных свойств не было, когда приложение Java загрузило файл свойств, то у нас есть явная динамическая проверка типов. Если мы не проверяем наличие непредвиденных (например, неназванных) свойств, у нас есть источник ошибок. Вещи становятся еще более беспорядочными, если вы хотите, чтобы типы значений свойств были чем-то иным, чем String.

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

И на этом этапе мы должны признать, что лучшим решением будет использование XML в качестве представления файла свойств, редактор с управляемой XML-схемой для редактирования файлов свойств и JAXP или что-то в этом роде для сопоставления файла свойств с Java API ,

+0

Я не понял, что именно вы подразумеваете под "и, следовательно, меняете" тип "файла" ... Но Я думаю, что вы беспокоитесь, это разные типы данных в файле? Если так; для этого случая типы возврата всегда являются String ... Поэтому добавление новой записи в файл вызовет генератор для генерации нового метода доступа ... – erdogany

+0

@erdogany: Нет. Я говорю об именах свойств, которые меняются. Если вы прочитаете вопрос, вы увидите, что OP хочет сопоставить каждое свойство с отдельным методом getter, чье имя получено из имени свойства. –

1

Еще один способ - использовать структуру привязки данных, которая делает это. Даже тот, который, по-видимому, не поддерживает напрямую, может работать: например, Jackson Процессор JSON позволит сделать это следующим образом:

ObjectMapper m = new ObjectMapper(); MyBean bean = m.convertValue (свойства, MyBean.class); // (примечание: требуется последний код из соединительной линии, в противном случае нужно сначала записать, прочитать)

, который работает до тех пор, пока записи в таблице свойств соответствуют свойствам логического компонента, а значения String могут быть преобразованы в соответствующие базовые значения.

0

Я думаю, что это решит вашу проблему Я написал об этой структуре свойств за последний год. Он предоставит несколько способов загрузки свойств и их также сильно набрал.

Посмотрите http://sourceforge.net/projects/jhpropertiestyp/

Это открытый исходный код и полностью документированы

Вот мое краткое описание от SourceForge:

JHPropertiesTyped will give the developer strongly typed properties. Easy to integrate in existing projects. Handled by a large series for property types. Gives the ability to one-line initialize properties via property IO implementations. Gives the developer the ability to create own property types and property io's. Web demo is also available, screenshots shown above. Also have a standard implementation for a web front end to manage properties, if you choose to use it. 

Complete documentation, tutorial, javadoc, faq etc is a available on the project webpage. 
Смежные вопросы