переплет курицы и яиц - PullRequest
1 голос
/ 08 ноября 2011

Хорошо, вот мой пример использования:

У меня есть следующие классы, каждый из которых инкапсулирует экземпляр следующего в строке.Итак:

A -> B -> C -> D

Например: в классе A у меня есть экземпляр класса B, а в классе BI - экземпляр C и так далее.

Я пытаюсь преобразовать логику загрузки \ инициализации \ впрыска в гибридную систему Spring.Общая идея состоит в том, что B, C и D должны будут более или менее быть ApplicationContextAware.Под этим я подразумеваю, что они на самом деле не будут реализовывать этот интерфейс, а вместо этого потребуют ApplicationContext в качестве параметра конструктора.Таким образом, в гибридном подходе (где разработчик не использует Spring для инициализации экземпляра) они должны по крайней мере передать ApplicationContext, чтобы можно было подключить дополнительные bean-компоненты.Проблема в том, что для того, чтобы Spring-контейнер загружал бины, мне теперь нужно передать ApplicationContext в XML.Но, насколько я могу судить, нет хорошего способа сделать это.

Я пробовал что-то вроде этого:

public class ApplicationContextPlaceholder implements ApplicationContextAware {

    private ApplicationContext _applicationContext;

    public void setApplicationContext( final ApplicationContext applicationContext ) throws BeansException {
        _applicationContext = applicationContext;
    }

    public ApplicationContext getApplicationContext() {
        return _applicationContext;
    }

}

<bean id="a" class="com.company.A">
    <constructor-arg>
        <bean id="applicationContext" class="com.company.ApplicationContextPlaceholder" />
    </constructor-arg>
</bean>

Но, очевидно, это не имеет никакого смысла, поскольку ApplicationContextPlaceholder не на самом деле и ApplicationContext.Я также искал способы ссылки на контекст внутри XML, но ничего не нашел.

Кто-нибудь знает элегантное решение проблемы такого типа?

РЕДАКТИРОВАТЬ # 1:

Я думал об этом, и я мог бы ApplicationContextPlaceholder также реализовать ApplicationContext и просто делегировать введенному контексту, и тогда мне пришло в голову, что, может быть, просто возможноэто было уже весной ... но, насколько я могу судить, нет.

РЕДАКТИРОВАТЬ # 2:

Причина, по которой каждый класс нуждается в ApplicationContextчто если разработчик желает переопределить один из классов в цепочке (скажем, C для аргументации).В этом случае дочернему классу C все еще нужно будет загрузить D через Spring.

Ответы [ 2 ]

1 голос
/ 08 ноября 2011

Если класс не предоставляет дополнительные функции сантехники, вам следует избегать показа ApplicationContext.Цитирование ссылки на Spring: in general you should avoid it, because it couples the code to Spring and does not follow the Inversion of Control style.

Если вы предоставляете дополнительную функциональность (например, класс фабрики, который использует ApplicationContext для сборки объектов), то это разумнореализовать ApplicationContextAware, поскольку ваша функциональность уже привязана к Spring.

Если вы рассмотрели альтернативы внедрение зависимостей и решили внедрить ApplicationContext в свои компоненты, ваш *Класс 1014 * (я бы держался в стороне от префикса Placeholder, чтобы избежать путаницы с заполнителями свойств Spring ), безусловно, является решением.(Поскольку это ваш собственный класс, почему бы не расширить ApplicationObjectSupport для дополнительной функциональности.)

Этот класс необходимо будет определить и инициализировать в вашей конфигурации, например:

<bean id="appCtxHolder" class="ApplicationContextHolder" />

Поскольку ApplicationContextHolder реализует ApplicationContextAware, Spring введет ApplicationContext в appCtxHolder при его инициализации.Вы можете использовать его для инъекции в конструктор, например:

<bean id="a" class="com.company.A">
    <constructor-arg>
        <bean factory-bean="appCtxHolder" factory-method="getApplicationContext" />
    </constructor-arg>
</bean>
0 голосов
/ 08 ноября 2011

ApplicationContextPlaceholder может иметь все статическое. В этом случае вам не нужно передавать ApplicationContext, когда API запрашивает определенный боб, вы можете проверить, имеет ли он значение null, и если это так, загрузить его, используя ApplicationContext из ApplicationContextPlaceholder. Это предполагает, что инъекция на основе сеттера, если вы делаете конструктор на основе, вы также можете инициировать bean-компоненты в конструкторе.

...