There is still a fair amounf of JBoss ESB (and SOA-P) users that use a lot of Spring in their development. Now, I know that we support Spring through our AbstractSpringAction, however this has a number of disadvantages:
- You have to extend a JBoss ESB class, which makes the action harder to unit test.
- The AbstractSpringAction creates an applicationcontext itsetf. This means that when you require multiple Spring-based actions in your pipeline, or if you define multiple services in a jboss-esb.xml which all use a AbstractSpringAction, you end up with multiple Spring ApplicationContexts loaded.
The introduction of annotated ESB actions made writing, and especially testing, of ESB actions a lot easier. However, you can't use that approach when you want to use Spring. So I've been working out a way to improve our support for Spring. The basic idea is this:
- We define a JBoss MicroContainer bean which can be loaded via a 'jboss-beans.xml' file and which is responsible for loading a Spring ApplicationContext. The bean can be based on Spring's own ContextLoaderListener and ContextLoader beans (which are responsible for loading an ApplicationContext in web environment). We actually create a sort of EsbContextLoader class. I've been working on an implementation and it's almost finished. We deploy this bean via, for example, a 'spring-jboss-beans.xml' file in the '.esb' archive, just like any other resource we require (e.g. JBoss Messaging Queue). We can define a dependency on this MC bean via the deployment.xml.
- We create a new annotation, for example something like @InjectSpringBean(bean="mySpringBean"). The implementation of this annotation will either use the new EsbContextLoader bean or Spring's SingletonBeanFactoryLocator mechanism to retrieve the ApplicationContext of the current .esb archive and inject the bean into the action.
The advantages of this approach are:
- One only has to define a single application context for a service or .esb archive.
- One can inject Spring beans in POJO actions, which eases testing.
Overall, the integration will look a lot better in my opinion and will definitely make development a lot easier.
Now, my problem is that I have not yet found a way to implement a new (custom) annotation. The BeanContainerAction (which is the base action for annotated actions) is loaded by the ActionProcessingPipeline, and I have not yet found a way to insert my own implementation (subclass) of BeanContainerAction which can support my new annotation. Neither have I found a way to insert, for example, a subclass of ActionProcessingPipeline which would be able to load a custom 'BeanContainerAction'.
So my questions are:
- Do you like my new idea for better Spring support? Is it something that we want to include and support in JBoss ESB and SOA-P?
- Can someone help me with defining new annotation's, hopefully by making the annotation support a bit more extendable?