5.7. EJB Integration
Although there is overlap between EJB and Spring, combining the two component models is common. It consists of components of one type delegating functionality to components of another type. The recommended practice is to provide the delegate components through injection, which can happen in any direction (Spring to EJB and EJB to Spring).
5.7.1. Injecting Spring Beans into EJBs
Red Hat JBoss Enterprise Application Platform 6 provides the following two major options of injecting Spring beans into EJBs:
- Using Spring's native support for EJB integration
- Using Snowdrop with Spring
5.7.1.1. Using Spring's Native Support for EJB Integration
Spring supports injection into EJBs through SpringBeanAutowiringInterceptor, which honors the @Autowired annotation.
Example 5.23. Injecting Spring Bean into EJB Using Spring's Native Support
@Stateless @Interceptors(SpringBeanAutowiringInterceptor.class) public class InjectedEjbImpl implements InjectedEjb { @Autowired private SpringBean springBean; }
The injected Spring beans are retrieved from an ApplicationContext located using a ContextSingletonBeanFactoryLocator, which uses a two-step method for locating contexts. The locator relies on the existence of one or more files named
beanRefContext.xml on the classpath (that is, it performs a 'classpath*:beanRefContext.xml' lookup), which contains a single application context definition.
Example 5.24. Simple beanRefContext.xml File Used by a ContextSingletonBeanFactoryLocator and the Corresponding simpleContext.xml
<beans> <bean class="org.springframework.context.support.ClassPathXmlApplicationContext"> <constructor-arg value="classpath*:simpleContext.xml" /> </bean> </beans
<beans> <bean id="springBean" class="example.SpringBean"/> </beans>
5.7.1.2. Using Snowdrop with Spring
Snowdrop is a package of Red Hat JBoss Enterprise Application Platform specific extensions to Spring, which are included in JBoss Web Framework Kit. This section provides an overview of injecting Spring beans into EJBs using Snowdrop support. For details and a more elaborate example, refer the Snowdrop User Guide and the Sportsclub Example.
Snowdrop supports the bootstrapping of Spring application contexts through JBoss Enterprise Application Platform specific Spring deployer. The deployer identifies Spring bean configuration files, (regular application context XML definitions) which are deployed in the META-INF directory of a deployable module (EAR, WAR, or EJB-JAR), and matches a specific pattern (by default, *-spring.xml). It bootstraps ApplicationContexts, which are further registered in JNDI under a name that can be configured from within the context definition.
Example 5.25. Spring Beans Configuration File (example-spring.xml)
<beans> <description>BeanFactory=(MyApp)</description> <bean id="springBean" class="example.SpringBean"/> </beans>
The Spring deployer bootstraps a context that contains a springBean bean and registers it in JNDI under the MyApp name.
You can inject beans defined in such contexts into EJBs, by using the Snowdrop specific SpringLifecycleInterceptor and @Spring annotation.
Example 5.26. Injecting Spring Bean into EJB Using Snowdrop
@Stateless @Interceptors(SpringLifecycleInterceptor.class) public class InjectedEjbImpl implements InjectedEjb { @Spring(bean = "springBean", jndiName = "MyApp") private SpringBean springBean; /* rest of the class definition omitted */ }
5.7.2. Accessing EJBs from Spring Beans
You can inject stateless EJBs into Spring components in the following two ways:
- Using EJB reference bean definitions
- Using the @EJB annotation in Spring
You can define EJB references as Spring beans using the
<jee:local-slsb>/<jee:remote-slsb> elements.
Example 5.27. Defining EJB Reference as Spring Bean
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd"> <jee:local-slsb id="ejbReference" jndi-name="java:global/example/example-ejb/ExampleImpl" business-interface="example.ExampleEjb"/> <bean id="consumerBean" class="example.ConsumerBean"> <property name="ejbReference" ref="ejbReference"/> </bean> </beans>
The EJB references are regular Spring beans and can be injected as any other Spring bean.
Example 5.28. Injecting EJB Reference Defined as Spring Bean
public class ConsumerBean { @Autowire ExampleEjb exampleEJB; }
Spring also supports injection directly with EJB references, as shown in the following example:
Example 5.29. Injecting an EJB Using Annotations
public class ConsumerBean { @EJB(mappedName="java:global/example/example-ejb/ExampleImpl") ExampleEjb exampleEJB; }
Unlike @EJB references in EJBs, which may not specify a name or mappedName and relies upon the container to resolve the reference automatically, @EJB references in Spring beans must specify the JNDI location where the EJB is expected to be found.