Как управлять несколькими версиями классов одновременно?
Мы внедряем корпоративное финансовое веб-приложение. Мы используем Spring, Hibernate, Oracle(DB), JSF. Требования меняются на этапе обслуживания программного обеспечения, и мы должны иметь несколько версий некоторых объектов (также менеджеров, форм,... классов) одновременно из-за совместимости с предыдущей версией программного обеспечения. Эти изменения классов включают в себя: Добавить / удалить поля, Изменить поля, Добавить / удалить класс,... В общем, эта проблема запускает несколько версий программного обеспечения одновременно. Пожалуйста, помогите мне найти решение этой проблемы.
Разъяснение:
Эта проблема аналогична "изменчивости во времени" в линейке программных продуктов (для получения дополнительной информации см. Elsner_vamos2010). Это означает, что у нас может быть несколько версий одного класса одновременно, и мы должны получить класс с параметром (или датой). В каждой дате должна использоваться одна версия класса из-за совместимости с состоянием программы на эту дату. Мы решаем эту проблему для класса Bean с помощью XML-файла и получаем версию класса с датой. Итак, программа знает, какой компонент должен быть запущен для этого состояния программы (дата других объектов).
Но мы не можем решить это для других типов объектов весной, таких как entity, jsp, form?
4 ответа
Вы смотрели в OSGi? Одной из функций, которую он предоставляет, является возможность для разных клиентских классов одновременно получать доступ к различным версиям классов, от которых они зависят. В любом случае, я так понимаю, хотя сам этим не пользовался.
Вы можете развернуть разные версии вашего проекта в разных WAR /EAR. В этом случае ваш контейнер позаботится о них автоматически. Каждая война будет загружена своим собственным загрузчиком классов, поэтому разные версии одного и того же класса (имя пакета и класса) не будут пересекаться. Достаточно ли хорош этот вариант?
Трудно сказать, возможно ли это в вашем случае, но я бы постарался не дурачиться с Classloaders. Сам по себе это сложная область, и WebAppServers, как правило, делают свое дело и с Classloaders.
Я бы попытался сделать это двумя отдельными веб-приложениями, возможно, размещенными на одном сервере и обменивающимися данными через базу данных (в любом случае, если у вас есть приложение для вашего приложения)
Прислушайтесь к совету Йенса Шаудера и избегайте забавных манипуляций с загрузкой классов.
Если мы говорим о WebServices, EJB или аналогичных интерфейсах, которые ваше приложение должно поддерживать в нескольких версиях, возможно, вы можете использовать подход посредника ESB, который преобразует (где это возможно) Vn-x запросы и ответы в Vn (где n означает твоя последняя версия). Это если вы можете преобразовать одно сообщение в другое, используя только сопоставления, простые функции или агрегаты (например, обработку XSLT или XQuery) и вам не нужно сохранять состояние между запросами. Любой приличный сервисный автобус сделает это.
В тех случаях, когда преобразование без сохранения состояния невозможно, вы можете разработать / адаптировать свой код так, чтобы версия Vn поддерживала API-интерфейсы Vn, Vn-1, Vn-2.... Возможно, вам придется использовать фасады версий для устранения неоднозначности операций / методов с одинаковой сигнатурой (v1 putX может вести себя иначе, чем v2 putX). Это позволяет вам изменять имя их реализации в коде Vn, сохраняя его на фасаде для соответствующей версии. Очевидно, что внешние системы видят только фасады.
Если вы не можете этого сделать, то ваши разные приложения должны быть развернуты отдельно.
Наконец, ваша схема.
Если вы применяете подход, в котором последняя версия поддерживает предыдущие API, то ваше приложение Vn является единственным, кто обращается к базе данных. Вы должны адаптировать свою схему к ее потребностям и перенести данные из более старой версии схемы, если они существуют. Готово.
Если вы этого не сделаете, у вас есть несколько версий вашего приложения, работающих и обращающихся к БД. В этом случае вам нужно, чтобы ваша "конкретная схема" БД поддерживала разные "логические схемы". Смотрите эту книгу о рефакторинге базы данных. Это предполагает использование нескольких методов, в соответствии с которыми ваша схема поддерживает взаимодействие с несколькими версиями приложения посредством умного использования триггеров, представлений, синонимов и т. Д. Это кажется сложным, но очень выполнимым.