Доступ к устаревшим экземплярам объектов вне контейнера из бинов Spring - PullRequest
0 голосов
/ 17 февраля 2010

У нас есть устаревшая система, в которой для создания и предоставления всех сервисных объектов используется что-то вроде сервисного локатора:

class ServiceLocator {

    ServiceA serviceA;
    ServiceB serviceB;

    public ServiceLocator () {
        serviceA = ...;
        serviceB = ...;
    }

    public ServiceA getServiceA() {
        return serviceA;
    }

    public ServiceB getServiceB() {
        return serviceB;
    }
}

(представьте себе еще 70 полей и геттеров ...)

Этот объект затем передается из класса в класс для предоставления доступа к объектам службы.

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

В отличие от вышеупомянутой ситуации, мы уже знаем, как мы получим доступ к объектам, созданным пружинными бобами, из нашего унаследованного кода. Наша проблема - объекты, которые мы планируем создать с помощью Spring, которым нужны любые сервисные объекты, созданные вне контекста Spring.

Мы придумали следующее решение:

Создайте статический метод доступа для ServiceLocator и установите его в конструкторе, загрузите объект контекста приложения Spring. В конфигурации Spring создайте bean-компонент для ServiceLocator со статическим средством доступа, как описано в разделе 3.3.2.2 в справочнике Spring:

<bean id="serviceLocator" 
  class="ServiceLocator"
  factory-method="getInstance"/>

для каждого Сервиса создайте другой bean-компонент, используя «метод фабрики экземпляров», как описано в Разделе 3.3.2.3:

<bean id="serviceA"
  factory-bean="serviceLocator"
  factory-method="getServiceA"/>

Создайте другие bean-компоненты, ссылающиеся на эти "фиктивные bean-компоненты".

Полагаю, это сработает, но создает много ненужных псевдо-настроек. Я бы предпочел что-то вроде этого:

"Если на компонент ссылаются, а этот компонент не определен явно, найдите метод с необходимой сигнатурой и именем в классе ServiceLocator и используйте этот объект."

Возможно ли это сделать? Существуют ли какие-либо точки входа в процесс создания экземпляров Spring Bean, о которых я не знаю и которые можно использовать здесь? Могу ли я сделать это путем создания подкласса класса контекста приложения Spring?

Любая помощь будет принята с благодарностью!

1 Ответ

1 голос
/ 17 февраля 2010

Вы можете определить BeanFactoryPostProcessor для заполнения контекста приложения бинами из ServiceLocator.

В BeanFactoryPostProcessor используйте beanFactory.registerSingleton(...) для добавления полностью созданного экземпляра компонента или ((BeanDefinitionRegistry) beanFactory).registerBeanDefinition(...) для добавления определения (обратите внимание, что некоторые контексты приложения могут не реализовывать BeanDefinitionRegistry, хотя все типичные контексты реализуют его).

...