关于将SipServlet的SipFactory注入到JavaEE 6的Bean中的折腾
2013-11-20 20:50
330 查看
折腾了几天终于比较满意地(Least-intrusive,Most-portable)解决了这个问题,学到了不少东西。特分享如下。
基本环境: Mobicents SipServlet 3.0.0-Snapshot, JBoss AS 7.13, JavaEE 6
需求:用JavaEE6技术重构一个基于Mobicents做的VOIP的项目,本文只分享用CDI和EJB3.1的注解实现依赖注入的经验。
问题:如何便捷地将Mobicents的SipFactory注入到普通的bean(CDI管理)中,或者EJB3.1的bean中?
尝试1:直接@Resource。
分析:经过艰苦卓绝的调查取证,我认为我找到了部分原因... 按Mobicents官方的说法,SipFactory只有在SipServlet容器Context启动时才会构建,而SipServlet容器是随着第一个SipServlet的初始化启动的。(注意默认都是Lazy Loading的)。也就意味着有可能上面的MyBean(即便为Stateless)需要注入和使用SipFactory的时候,它还没有准备好!即便有所谓的三种获取方式(JNDI调用,mappedName,和@Resource),上面的问题还是解决不了。尤其是如果需要加上@Startup给一个@Singleton的时候,它实例化的时后SipFactory肯定没准备好。
尝试2:基于上面分析,只能放弃上面三种方式。接下来自然就想到监听SipServletContext的事件,等它初始化完成SipFactory肯定就可以用了。
分析:注意到此时我们有了Facade模式和Event/Listener的思想。我们想用POJO模式的Facade封装SipServlet容器的工具类SipFactory,一方面屏蔽它的依赖注入方式,另一方面还有别的Facade的好处:比如简化实用,封装异常等等。可惜,可惜,上面的方式行不通...
最终尝试:JavaEE 6 javax.enterprise.event.* !
分析:注意使用JavaEE 6的Event/@Observes大大简化监听者模式的实现而且注入性小。实现了低耦合。
基本环境: Mobicents SipServlet 3.0.0-Snapshot, JBoss AS 7.13, JavaEE 6
需求:用JavaEE6技术重构一个基于Mobicents做的VOIP的项目,本文只分享用CDI和EJB3.1的注解实现依赖注入的经验。
问题:如何便捷地将Mobicents的SipFactory注入到普通的bean(CDI管理)中,或者EJB3.1的bean中?
尝试1:直接@Resource。
public class MySipServlet extends SipServlet { @Resource private SipFactory sipFactory; ... } @Singleton public class MyBean { @Resource private SipFactory sipFactory; }结果:在SipServlet(MySipServlet)中会成功注入。一般的bean中(MyBean)不能成功注入,时而有NPE。
分析:经过艰苦卓绝的调查取证,我认为我找到了部分原因... 按Mobicents官方的说法,SipFactory只有在SipServlet容器Context启动时才会构建,而SipServlet容器是随着第一个SipServlet的初始化启动的。(注意默认都是Lazy Loading的)。也就意味着有可能上面的MyBean(即便为Stateless)需要注入和使用SipFactory的时候,它还没有准备好!即便有所谓的三种获取方式(JNDI调用,mappedName,和@Resource),上面的问题还是解决不了。尤其是如果需要加上@Startup给一个@Singleton的时候,它实例化的时后SipFactory肯定没准备好。
尝试2:基于上面分析,只能放弃上面三种方式。接下来自然就想到监听SipServletContext的事件,等它初始化完成SipFactory肯定就可以用了。
public class SipServletFacade1 implements SipServletListener { private SipFactory sipFactory; } public class SipServletFacade2 extends SipServlet implements SipServletListener { private SipFactory sipFactory; }结果:SipServletFacade1貌似很简单但是好像Mobicents实现的容器不接受(只有SipServlet才能作为SipServletListener?),所以失败。SipServletFacade2侵入性太强(SipServlet应该在展现层而不是到业务层),所以还是早早放弃吧!
分析:注意到此时我们有了Facade模式和Event/Listener的思想。我们想用POJO模式的Facade封装SipServlet容器的工具类SipFactory,一方面屏蔽它的依赖注入方式,另一方面还有别的Facade的好处:比如简化实用,封装异常等等。可惜,可惜,上面的方式行不通...
最终尝试:JavaEE 6 javax.enterprise.event.* !
分析:注意使用JavaEE 6的Event/@Observes大大简化监听者模式的实现而且注入性小。实现了低耦合。
public class MySipServlet extends SipServlet() { @Resource SipFactory sipFactory; @Inject private Event<MyEvent> myEventEmitter; ... @Override public void init() { myEventEmitter.fire(new MyEvent(sipFactory)); } public class SipServletFacade { private SipFactory sipFactory; public void sipServletInit(@Observes MyEvent myEvent) { sipFactory = myEvent.getSipFactory(); } }本文出自 “我劝天公重抖擞” 博客,请务必保留此出处http://waynecui.blog.51cto.com/8231128/1329253
相关文章推荐
- 关于BeanFactory,FactoryBean,ObjectFactory
- org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'selectcommoninfo' defined in ServletCont
- Error creating bean with name 'sessionFactory' defined in ServletContext resource
- 【spring】在servlet中注入spring的bean,servlet容器和spring容器
- Spring强制向servlet中注入bean的方法
- 关于资源文件中的字段是如何注入到spring bean中的
- servlet中注入spring管理的bean
- Spring IoC 依赖注入 BeanFactory ApplicationContext WebApplicationContext
- 关于javaEE,如何在Tomcat启动时加载servlet
- Spring+Servlet整合(如何向Servlet注入属性(转),servlet获取spring容器中的bean)
- Servlet自动注入Spring容器中的Bean解决方法
- Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean
- BeanFactory and ServletContext
- 注入FactoryBean失败分析+解决方案
- Error creating bean with name 'sessionFactory' defined in ServletContext resource 解决方法之一
- spring3.2 定时器 SchedulerFactoryBean 注入错误
- struts2与spring集成时,关于Action类中成员bean自动注入的问题
- FactoryBean在XML中的依赖注入方法
- 项目中遇到关于OpenSessionInViewFilter的默认sessionFactoryBeanName的问题
- 一个和spring整合的依赖注入的servlet,子类可自动装配依赖Bean