Трудно придумать название для этого!У меня есть боб, который инициализируется в контейнере пружины.Он загружает классы, которые также создают объекты из файлов, используя загрузчики классов Spring.Некоторые из этих объектов могут зависеть от дорогих объектов, и я хотел бы, чтобы эти объекты были инициализированы в родительском объекте.Хорошо, я не могу объяснить словами на упрощенном примере:
public class MainLoader {
public static void main(String[] args) {
XmlBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("top-context.xml"));
ChildLoader childLoader = (ChildLoader)beanFactory.getBean("childLoader");
childLoader.loadChildAndDoSomething("message1.xml");
childLoader.loadChildAndDoSomething("message2.xml");
}
}
public class ChildLoader {
public void loadChildAndDoSomething(String childContextfile){
XmlBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource(childContextfile));
ClassThatDoesStuff classThatDoesStuff = (ClassThatDoesStuff)beanFactory.getBean("classThatDoesStuff");
classThatDoesStuff.saySomething();
}
}
public class ClassThatDoesStuff {
private ReallyExpensiveService reallyExpensiveService;
private String messageStart;
public void saySomething(){
System.out.println(messageStart + reallyExpensiveService.getName());
}
// .. field setters removed for brevity
}
public class ReallyExpensiveService {
public String getName(){
return "Joe";
}
}
У них есть следующие компоненты в файлах:
top-context.xml:
<bean id="childLoader" class="com.mark.test.ChildLoader" />
message1.xml (message2.xml аналогично):
<bean id="classThatDoesStuff" class="com.mark.test.ClassThatDoesStuff">
<property name="messageStart" value = "Hello! " />
<property name ="reallyExpensiveService" ref="theExpensiveserviceReference" />
</bean>
<bean id="theExpensiveserviceReference" class="com.mark.test.ReallyExpensiveService" />
При их запуске вы получите ожидаемое:
Hello! Joe
Goodbye! Joe
Единственная проблема здесь заключается в том, что "«Действительно, дорогой сервис» создается и кэшируется Spring каждый раз.Это подтверждается журналом.Лучше загружать любые сервисы, которые могут понадобиться классам "ClassThatDoesStuff" (представьте, что это интерфейс), когда инициализируется MainLoader.Т.е. (концептуально) изменить контекстные файлы пружины на:
top-context.xml:
<bean id="childLoader" class="com.mark.test.ChildLoader" />
<bean id="theExpensiveserviceReference" class="com.mark.test.ReallyExpensiveService" />
message1 / 2.xml
<bean id="classThatDoesStuff" class="com.mark.test.ClassThatDoesStuff"
autoWired="byType">
<property name="messageStart" value = "Hello! " />
</bean>
Я понимаю, чтоВыход из этого состоит в том, чтобы ClassThatDoeStuff имел установщик для службы и устанавливал значение из дочернего контейнера, который сам вводил его через основной контекст.Но представьте, что есть произвольные сервисы, и каждый из реализаторов ClassThatDoesStuff использовал разные. Есть ли способ, чтобы это работало в Spring?