#java #spring
#java #весна
Вопрос:
Есть ли какой-либо способ ссылаться на текущий контекст приложения в файле конфигурации компонента в Spring?
Я пытаюсь сделать что-то вроде этого:
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<bean id="some-bean-name" class="com.company.SomeClass">
<constructor-arg>
<!-- obviously this isn't right -->
<bean ref=#{this}/>
</constructor-arg>
</bean>
Проблема в том, что SomeClass
в его конструкторе требуется экземпляр ApplicationContext. Есть ли какой-либо способ получить ссылку на ApplicationContext, который загружает компоненты? Я знаю, что могу выполнить всю загрузку в XML, но это не совсем то, что мне нужно, поскольку мне нужно выполнить загрузку компонента в моем Java-коде.
Комментарии:
1. Поэтому в идеале ваши классы не должны знать о ApplicationContext. Это приводит к тому, что service-locator вместо выполнения инъекции на основе конструктора. Но иногда вам это может понадобиться. Таким образом, «ApplicationContextAware» (боковая загрузка) является наилучшим вариантом. Просто убедитесь, что вы спрашиваете себя ~ зачем вам нужен ApplicationContext…..
Ответ №1:
Вы смотрели на реализацию ApplicationContextAware
? Это не входит в конструктор, но это происходит перед init()
вызовом и произойдет сразу после заполнения свойств компонента.
Вызывается после заполнения обычных свойств компонента, но перед обратным вызовом init, таким как InitializingBean.afterPropertiesSet() или пользовательский метод инициализации. Вызывается после загрузки ресурсов.setResourceLoader(org.springframework.core.io.ResourceLoader), ApplicationEventPublisherAware.setApplicationEventPublisher(org.springframework.context.ApplicationEventPublisher) и MessageSourceAware, если применимо.
public class SomeClass implements ApplicationContextAware {
//your class definition
private ApplicationContext myContext;
public void setApplicationContext(ApplicationContext context) throws BeansException {
myContext = context;
//load beans here maybe?
}
}
Вы также можете @Autowire(d)
использовать это, если используете Spring 2.5 или более позднюю версию.
public class SomeClass {
//your class definition
@Autowired
private ApplicationContext myContext;
}
Конечно, выполнение любого из этих действий привяжет ваш код к Spring.
Комментарии:
1. Есть ли что-то, что вам нужно сделать в XML, чтобы заставить это работать? Я пробовал использовать интерфейсный подход, но установщик, похоже, не вызывается.
2.
SomeClass
должна управлятьсяApplicationContext
. Либо с помощью конфигурации xml, либо с помощью конфигурации аннотаций.3. Я думаю, что вижу это сейчас, это работает только в том случае, если компоненты загружены с помощью пружины, в противном случае вам придется вручную вызывать установщик.
4. Ну, вы, вероятно, не стали бы вызывать установщик самостоятельно. Он разработан Spring как способ получения ваших управляемых компонентов Spring
ApplicationContext
. Единственное место, где я ожидал бы увидеть, что кто-то назовет это сам, — это если они создают какое-то расширение Spring, и они хотели предоставить аналогичную функциональность своим расширениям.5. Было бы неплохо, если бы то, о чем я просил, было доступно, но это работает для меня. Спасибо!