First, there was EJB 2.1 with countless XML files all over. It won't be such a big exaggeration to say that for every line of business code you had to create at least 10 lines of framework code and two pages of XML. Local and remote interfaces, manual JNDI lookup, triply nested try-catches, checked RemoteExceptions everywhere... this was enterprise. There were even tools to generate some of this boilerplate automatically.
Then couple of guys came and created Spring framework. After being forced to cast by obscure PortableRemoteObject.narrow() it was like taking a deep breath of fresh air, like writing poetry after working in coal mine. Time went by (BTW do you remember how many years ago was the last major JRE release?) and Sun learnt their lesson. EJB 3.0 was even simpler compared to Spring, XML-free, annotations, dependency injection. 3.1 was another great step toward simplicity, being more and more often compared to Spring. Logically current state of the art EJB specification might be considered as a subset of what Spring offers, I am actually surprised why there is no EJB spec. implementation in plain Spring (oh, wait...), considering its out-of-the-box support for JPA 1.0/2.0, JSR-250, JSR-330, JAX-WS/RS compatible solutions and others. But even though, Spring framework is nowadays perceived as a slow, heavyweight and hard to maintain, mainly due to reliance on XML descriptors. Once simple, now Spring is a whipping boy in the JEE framework battle.
I don't like politics, I won't defend my beloved framework writing lengthy essays. Instead I will take simple, but not trivial Spring application and quickly rewrite it so that it won't use XML. Not reduce the amount of XML, not leave only few untouchable lines. No XML - at all.
For the purposes of this article I created very simple Spring web application (base version under xml branch, final on master on my GitHub account) using JDBC, JMS and JMX, just not to make things trivial. Every change I made to the source code will be reflected in a separate commit to this repository. Step by step I will be removing XML configuration until there will be no Spring XML left. This is where we start:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core-5.4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:mbean-export />
<bean id="fooService" class="com.blogspot.nurkiewicz.FooService">
<property name="jmsOperations" ref="jmsTemplate" />
</bean>
<bean id="fooRequestProcessor" class="com.blogspot.nurkiewicz.FooRequestProcessor">
<property name="fooRepository" ref="fooRepository" />
</bean>
<bean id="fooRepository" class="com.blogspot.nurkiewicz.FooRepository" init-method="init">
<property name="jdbcOperations" ref="jdbcTemplate" />
</bean>
<!-- JDBC -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:~/workspace/h2/spring-noxmal;DB_CLOSE_ON_EXIT=FALSE;TRACE_LEVEL_FILE=4;AUTO_SERVER=TRUE" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="dataSource" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource" />
</bean>
<tx:annotation-driven />
<!-- JMS -->
<bean id="jmsConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
<constructor-arg>
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616" />
</bean>
</constructor-arg>
</bean>
<amq:queue id="requestsQueue" physicalName="requests" />
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<constructor-arg ref="jmsConnectionFactory" />
<property name="defaultDestination" ref="requestsQueue" />
</bean>
<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="jmsConnectionFactory" />
<property name="destination" ref="requestsQueue" />
<property name="sessionTransacted" value="true"/>
<property name="concurrentConsumers" value="5"/>
<property name="messageListener">
<bean class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
<constructor-arg ref="fooRequestProcessor" />
<property name="defaultListenerMethod" value="process"/>
</bean>
</property>
</bean>
</beans>









