<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
I also had an applicationContext.xml (under WEB-INF) that scanned for my own custom annotations. So that allowed my Action classes to use my custom annotations. With Struts2's native annotations, you don't need to worry about the struts-config.xml for result-jsp mappings either. Its all there in your action class. I even had advice around the action to capture timing stats thus implementing "seperation of concerns" to the hilt!! Well that took care of the web tier.
My app tier was EJB 3.0 based and I found that Spring had an interceptor that helped my cause. So my session facade had to be annotated with my custom Spring interceptor as shown here:
@Stateless(name = "HelloWorldService")
@Interceptors(MySpringBeanAutowiringInterceptor.class)
public class HelloWorldService implements HelloWorld, Serializable
The custom Spring interceptor essentially helps me to use a custom annotation (my own type for autowiring) in the EJB. The code for the interceptor looks like:
public class MySpringBeanAutowiringInterceptor extends SpringBeanAutowiringInterceptor
{
@Override
protected void configureBeanPostProcessor(AutowiredAnnotationBeanPostProcessor processor, Object target) {
processor.setAutowiredAnnotationType(CustomAutowiring.class);
}
}
Now here came the tricky part - I had to create the beanRefContext.xml for Spring and had to have it load up another context file that had information to setup Spring to search for my custom annotations as so -
<bean class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg type="java.lang.String" value="ejbApplicationContext.xml"/>
</bean>
In the ejbApplicationContext.xml, I setup the component-scan tag to search for my annotations. This worked though I was initially at a loss as to why I need to specify two context files to get dependencies to be injected by Spring. I found the reason for this on the Spring forums (by Juergen Hoeller) -
Essentially, your "beanRefContext.xml" file will typically define a ClassPathXmlApplicationContext which in turns loads your actual beans. The "beanRefContext.xml" mechanism allows multiple such shared ApplicationContexts to co-exist, differentiated by bean factory locators. In the default EJB3 case, simply define one such ApplicationContext which will be picked up automatically, regardless of name.
You can also read more on this in the Spring docs here. The other thing also was that I had to make sure I had the correct set of libraries in my EAR. Those libraries were:
- spring.jar
- asm-2.2.3.jar
- asm-commons-2.2.3.jar
- aspectjrt.jar
- aspectjweaver.jar
- common-annotations.jar
- commons-logging.jar
- log4j-1.2.14.jar
Overall, I found that the web side Struts2 integration with Spring seemed much more cleaner that the EJB one. At this point I would still recommend this approach, but make sure you have a little bit of time on your hands to get this working exactly the way you want it. If you are interested, I can further share any other information - just call out.
I will continue to tweak and research on the EJB implementation - but overall, this approach still makes for an interesting application design.
1 comment:
HI. I'm trying to do the same thing but I can't make it work. Can you put your example code available?
Thanks in advance
Post a Comment