Using Spring with EJB 3

Using Spring with EJB 3

By Robert. Filed in Java   |  
Tags: ejb , ioc , spring

TOP   del.icio.us digg

Back when we were planning the migration to Glassfish, I realised we would have two dependency-injection frameworks in use – EJB 3 and Spring. For obvious reasons, I wanted to know more about how these would interact. At the time (last July), I couldn’t find anyone who had used EJB 3 and Spring together – even Ben Alex from Interface21 hadn’t come across it. Six months later, and I still haven’t heard of anyone using Spring _from_ EJBs. Except for us.


There’s lots of reasons to use both EJB 3 and Spring. EJBs have benefits Spring doesn’t give – integration with things like Servlets and JSP tags, better integration with the container for monitoring and management, tool support, and so on. Spring has benefits as well – most notably, you don’t need the container, but also you get more control over the bean lifecycle. Together, they are a good complement.

But how do you get a Spring-managed bean from an EJB? The answer: dependency injection, of course. That is, with the aid of a EJB Interceptor:

[source='java']
public class SpringBeanInterceptor {

private BeanFactory beanFactory;

@PostConstruct public void configureSpringBeans(InvocationContext context) throws Exception {
for (Method method : context.getTarget().getClass().getMethods()) {
if (method.isAnnotationPresent(SpringBean.class)) {
Class springClass = method.getParameterTypes()[0];
String springName = determineSpringBeanName(method, springClass);
Object springBean = beanFactory().getBean(springName);
try {
method.invoke(context.getTarget(), springBean);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e.getCause());
}
}
}
context.proceed();
}

private String determineSpringBeanName(Method method, Class springClass) {
String springName = method.getAnnotation(SpringBean.class).value();
if (springName.length() > 0) {
springName = toCamelCase(springClass.getSimpleName());
}
return springName;
}

private String toCamelCase(String string) {
return Character.toLowerCase(string.charAt(0)) + string.substring(1, string.length());
}

private BeanFactory beanFactory() {
if (beanFactory == null) {
BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(”classpath*:beanRefContext.xml”);
BeanFactoryReference ref = locator.useBeanFactory(”applicationContext-service”);
beanFactory = ref.getFactory();
}
return beanFactory;
}
}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SpringBean {
String value() default “”;
}
[/source]

That’s it. This Interceptor will look over an EJB, after it’s created, and provides the Spring beans. This version looks for ’setter-methods’ with an @SpringBean annotation (you could also change it to look for fields), and looks up a corresponding bean from the Spring context (the ContextSingletonBeanFactoryLocator makes this possible).

Here’s how you would use it:

[source='java']
@Stateless
@Interceptors(SpringBeanInterceptor.class)
public class MyServiceBean implements MyService {
private MySpringBean bean;

@SpringBean public void setMySpringBean(MySpringBean bean) {
this.bean = bean;
}
}
[/source]

With this (and one other trick I’ll discuss soon), you can (nearly) seamless integrate EJB3 and Spring.

The one big limitation of this: with Stateless Session Beans, you can only inject stateless dependencies, and you can only inject them when the EJB is initialised.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值