This was an approach prototyped by Barry Kaplan almost a year ago.
Top level application configuration follows. Some notable features:
- No use of standard QF configuration file. Spring configures everything.
- More control of session configuration. For example, each session can use a different application instance.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <!-- Sets up core Spring objects for QFJ --> <import resource="classpath:quickfix/spring/quickfixj.appctx.xml"/> <bean id="messageStoreFactory" class="quickfix.spring.messagestore.MemoryMessageStoreFactory"/> <bean id="logFactory" class="quickfix.ScreenLogFactory"> <constructor-arg value="true"/> <constructor-arg value="true"/> <constructor-arg value="true"/> </bean> <bean id="dataDictionary" class="quickfix.spring.session.DataDictionary"> <property name="definition" ref="quickfix:FIX42"/> <property name="validateFieldsOutOfOrder" value="false"/> <property name="validateFieldsHaveValues" value="false"/> <property name="validateUserDefinedFields" value="false"/> </bean> <bean id="abstractInitiatorSession" abstract="true" class="quickfix.spring.session.InitiatorSessionFactoryBean"> <property name="dataDictionary" ref="dataDictionary"/> <property name="sessionSchedule" value="00:00:00, 24:00:00"/> <property name="heartbeatInterval" value="3"/> <property name="messageStoreFactory" ref="messageStoreFactory"/> <property name="logFactory" ref="logFactory"/> </bean> <!-- Sessions are configured directly in the Spring configuration --> <!-- There is no use of the standard QF configuration file --> <!-- Every session can be configured with a different application object, unlike QF --> <bean id="initiatorSession_A" parent="abstractInitiatorSession"> <property name="sessionID" value="FIX.4.2:senderCompIdA:targetCompIdA"/> <property name="application"> <bean class="quickfix.spring.transport.ConfigurationServer$LoggingApplication"> <property name="name" value="InitiatorA"/> </bean> </property> </bean> <bean id="initiatorSession_B" parent="abstractInitiatorSession"> <property name="sessionID" value="FIX.4.2:senderCompIdB:targetCompIdA"/> <property name="application"> <bean class="quickfix.spring.transport.ConfigurationServer$LoggingApplication"> <property name="name" value="InitiatorB"/> </bean> </property> </bean> <!-- --> <bean id="abstractAcceptor" abstract="true" class="quickfix.spring.session.AcceptorSessionFactoryBean"> <property name="application"> <bean class="quickfix.spring.transport.ConfigurationServer$LoggingApplication"> <property name="name" value="Acceptor"/> </bean> </property> <property name="dataDictionary" ref="dataDictionary"/> <property name="sessionSchedule" value="monday 00:00:00, sunday 24:00:00"/> <property name="messageStoreFactory" ref="messageStoreFactory"/> <property name="logFactory" ref="logFactory"/> </bean> <bean id="acceptorSession_A" parent="abstractAcceptor"> <property name="sessionID" value="FIX.4.2:targetCompIdA:senderCompIdA"/> </bean> <bean id="acceptorSession_B" parent="abstractAcceptor"> <property name="sessionID" value="FIX.4.2:targetCompIdA:senderCompIdB"/> </bean> </beans>
This is a mix-in style configuration for the network connections. By including a different file, a completely different transport could be used.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="quickfix:minaSocketInitiator" class="quickfix.transport.mina.MinaSocketInitiator"> <constructor-arg index="0" ref="quickfix:scheduledExecutorService"/> </bean> <bean id="quickfix:minaSocketInitiatorAwareProcessor" class="quickfix.spring.transport.mina.MinaSocketInitiatorAwareProcessor"> <property name="minaInitiator" ref="quickfix:minaSocketInitiator"/> </bean> <bean id="quickfix:minaSocketAcceptor" class="quickfix.transport.mina.MinaSocketAcceptor"/> <bean id="quickfix:minaSocketAcceptorAwareProcessor" class="quickfix.spring.transport.mina.MinaSocketAcceptorAwareProcessor"> <property name="minaAcceptor" ref="quickfix:minaSocketAcceptor"/> </bean> </beans>
quickfixj.appctx.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="_quickfix:propertyOverrideConfigurer" class="org.springframework.beans.factory.config.PropertyOverrideConfigurer"> <property name="location" value="classpath:quickfix.properties"/> <property name="ignoreResourceNotFound" value="true"/> </bean> <!-- TODO Document as available --> <bean id="quickfix:FIX42" class="org.springframework.core.io.ClassPathResource"> <constructor-arg value="FIX42.xml"/> </bean> <!-- TODO Document as available --> <bean id="quickfix:FIX43" class="org.springframework.core.io.ClassPathResource"> <constructor-arg value="FIX43.xml"/> </bean> <!-- TODO Document as available --> <bean id="quickfix:FIX44" class="org.springframework.core.io.ClassPathResource"> <constructor-arg value="FIX44.xml"/> </bean> <bean name="_quickfix:sessionSettingsAwareProcessor" class="quickfix.spring.sessionsettings.SessionSettingsAwareProcessor"/> <bean name="_quickfix:sessionSettings" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"> <property name="targetObject" ref="_quickfix:sessionSettingsAwareProcessor"/> <property name="propertyPath" value="sessionSettings"/> </bean> <bean name="_quickfix:cachingSessionFactoryAwareProcessor" class="quickfix.spring.session.CachingSessionFactoryAwareProcessor"> <property name="sessionSettings" ref="_quickfix:sessionSettings"/> </bean> <!-- TODO Document configurable property: corePoolSize --> <bean id="quickfix:scheduledExecutorService" class="quickfix.spring.ScheduledExecutorServiceFactoryBean"/> <bean name="_quickfix.transport:propertyEditors" class="org.springframework.beans.factory.config.CustomEditorConfigurer"> <property name="customEditors"> <map> <entry key="quickfix.SessionID"> <bean class="quickfix.spring.session.SessionIDPropertyEditor"/> </entry> <entry key="quickfix.spring.session.SessionSchedule"> <bean class="quickfix.spring.session.SessionSchedulePropertyEditor"/> </entry> <entry key="java.net.SocketAddress"> <bean class="quickfix.spring.transport.InetSocketAddressPropertyEditor"/> </entry> <entry key="java.net.InetSocketAddress"> <bean class="quickfix.spring.transport.InetSocketAddressPropertyEditor"/> </entry> </map> </property> </bean> </beans>