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

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

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

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

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

Например,

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

Ответы [ 7 ]

15 голосов
/ 23 апреля 2009

Для 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 - она ​​не позволит вашей настройке стать осиротевшей .

8 голосов
/ 23 апреля 2009

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

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

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

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

4 голосов
/ 23 апреля 2009

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

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

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

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

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

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

3 голосов
/ 23 апреля 2009

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

3 голосов
/ 23 апреля 2009

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

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

1 голос
/ 25 января 2011

Посмотрите на

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

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

1 голос
/ 23 апреля 2009

Хорошая цитата из АОП. Я добавлю Spring, который имеет очень хорошие встроенные функции AOP.

...