记录在Sungard工作时对ejb3.1的研究(1)--ejb3.1特性
2015-11-01 19:28 小晖的程序人生 阅读(404) 评论(0) 收藏 举报1. Aynchronous ejb call(异步ejb call)
我觉得这个是3.1最重要的新特性了。以往,无论stateful, stateless session bean都是同步的。那我们如果需要异步怎么办?只能Message driven bean了。而且使用MDB的话,碰到如下场景:
1. serviceA是一个非常耗时的任务,我们不知道需要多久结束。
2. 我们需要serviceA完成才能继续我们的logic
这时,我们设计程序就复杂了。我们需要创建一个temporary queue as replyto, 然后MDB完成后发送reply message。主线程那里需要listen to reply queue的message listener. 一担监听到message返回后就继续..有了aynchronous ejb call一切就简单了~
@Local(SchedulerServiceLocal.class) @Remote(SchedulerServiceRemote.class) @Stateless @TransactionManagement(TransactionManagementType.CONTAINER) @TransactionAttribute(TransactionAttributeType.REQUIRED) public class SchedulerServiceBean implements SchedulerService,TimedObject{ protected Logger log = LoggerFactory.getLogger(getClass()); @Resource public SessionContext ctx; @Asynchronous public Future<Boolean> startTimer() { boolean result = false; cancelAllTimer(); startCronTimer(); try { Thread.sleep(1000*10); } catch (InterruptedException e) { } result = true; return new AsyncResult<Boolean>(result); } }
主线程call 异步 方法:
Future<Boolean> result; if((AppServerContext.isJboss6()||AppServerContext.isJboss7())&&AppServerContext.isCluster()){ SchedulerService schedulerService = ServiceLocator.getInstance().getRemoteServiceByHAJNDI(SchedulerService.class); result = schedulerService.startTimer(); doSomethingElse();
}
可以看到aynchronous ejb cal返回的就是普通的future~
2. Global JNDI
以往,ejb的jndi lookup都需要depend on 应用服务器的实现。weblogic, jboss, websphere, sap netweaver生成的jndi五花八门。这样我们的程序需要支持不同javaee container的话,servicelocator就复杂了..每个应用服务器都要一个servicelocator的implementation..直到global jndi诞生,终于清静了.
我在Sungard只verify过weblogic12c和jboss eap6。 jboss AS6 部分支持ejb3.1, global jndi不支持.
3. singleton ejb
EJB3.1之前,Session bean被设计为单线程的模型,此模型要求同一时刻某一个bean的实例只能被一个线程使用,其中无状态会话bean采用实例池,而有状态会话bean采用激活钝化技术实现。
EJB3.1引入了注解@javax.ejb.Singleton,这个注解可以标注session bean为单实例的,类似与J2EE开源界的IOC容器的单例,但是EJB3.1中的单例区别于传统开源界的单例的不同之处就是:这种单例的实例是可以有状态的,以前我们都是将无状态的组建作为单例,但是EJB3.1以后,有状态的组件也可以声明为单例,这就是EJB3.1引入的并发控制模型,可以通过注解@javax.ejb.ConcurrencyManagement(CONTAINER)将bean声明为容器管理的并发,和传统的事物管理一样,EJB3.1也给了开发者灵活的选择,开发者还可以通过@javax.ejb.ConcurrencyManagement(BEAN)进行bean管理的并发,在采用了bean管理的并发以后,还可以采用@javax.ejb.Lock(WRITE)对bean的方法或者类进行注解,这里的lock注解其实类似于JAVA中read-write lock(读写锁)。
@Singleton @Startup @ConcurrencyManagement(ConcurrencyManagementType.CONTAINER) @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) public class AppInitialization { @EJB(beanInterface = InitProductsServiceLocal.class) private InitProductsService initProductsService; @PostConstruct public void startUp(){ initProductsService.init(); } private String status = "old"; @Lock(LockType.WRITE) @AccessTimeout(value=200000) public void setStatus(String newStatus) { try { Thread.sleep(1000*10); } catch (InterruptedException e) { e.printStackTrace(); } status = newStatus; } @Lock(LockType.READ) public String getStatus() { try { Thread.sleep(1000*10); } catch (InterruptedException e) { e.printStackTrace(); } return status; } }
4. more flexible way to create ejb timer.
https://docs.oracle.com/javaee/6/tutorial/doc/bnboy.html有详细的描述, 总体来说就是支持cron表达式了.
浙公网安备 33010602011771号