Как я могу расширить Java-код, сгенерированный JAXB, CXF или Hibernate tools?

StackOverflow https://stackoverflow.com/questions/780567

Вопрос

С сгенерированным исходным кодом Java, например

  • код, сгенерированный с помощью инструментов гибернации
  • код, сгенерированный с помощью привязки схемы JAXB (xjc)
  • код, сгенерированный с помощью WDSL2Java (cxf)

все сгенерированные классы являются типами "value object", без бизнес-логики.И если я добавлю методы к сгенерированному исходному коду, я потеряю эти методы, если повторю генерацию исходного кода.

Предлагают ли эти инструменты генерации кода Java способы "расширить" сгенерированный код?

Например,

  • чтобы переопределить метод toString (для ведения журнала)
  • для реализации шаблона посетителя (для анализа / проверки данных)
Это было полезно?

Решение

Для JAXB смотрите Добавление Поведений.

По сути, вы настраиваете JAXB на возврат пользовательского экземпляра объекта, который вы обычно ожидаете.В приведенном ниже примере вы создаете новый объект PersonEx, который расширяет объект JAXB Person.Этот механизм хорошо работает в том смысле, что вы производны от сгенерированных классов и вообще не изменяете классы или схемы JAXB.

package org.acme.foo.impl;

class PersonEx extends Person {
  @Override
  public void setName(String name) {
    if(name.length()<3) throw new IllegalArgumentException();
    super.setName(name);
  }
}

@XmlRegistry
class ObjectFactoryEx extends ObjectFactory {
  @Override
  Person createPerson() {
    return new PersonEx();
  }
}

Обратите внимание, что директива @Override важна в случае изменения вашего объекта JAXB - это предотвратит превращение вашей настройки в осиротевший.

Другие советы

Что касается гибернации, вы можете настроить файлы шаблонов, используемые при генерации кода, чтобы изменить их поведение.Если вы хотите настроить инструменты гибернации, вы можете отредактировать, например: дао/daohome.ftl

Вы даже можете добавить поля к выводу "toString()", редактируя .hbm.xml Файлы

...
<property name="note" type="string">
    <meta attribute="use-in-tostring">true</meta>
    <column name="note" />
</property>
...

Как для ведения журнала, так и для проверки вы можете рассмотреть возможность использования AOP с аспектомj (Я не рекомендую возиться с сгенерированным кодом, так как вам, возможно, захочется создавать его с нуля много раз).

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

К сожалению, java не поддерживает концепцию частичных классов, которая есть в c #.Они предназначены именно для решения такого рода проблем.

Вы должны посмотреть, поддерживают ли ваши инструменты генерации кода какую-либо форму значимых комментариев, которые ограничивают области, добавленные вами в класс (это маловероятно и не поможет, если вы модифицируете код, а не добавляете к нему)

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

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

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

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

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

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

Цитата из AOP - хорошая.Я добавлю Spring, в который встроены очень приятные функции AOP.

Взгляните на

http://code.google.com/p/jaxb-method-inserter/

Это небольшой плагин для JAXB, который я написал, он довольно прост в использовании.Надеюсь, это поможет

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top