蜻蜓8:ejb远程代理线程安全吗?
问题描述:
我有以下的情况,在客户耳边应用程序有CDI @ApplicationScoped
Bean上的@PostConstruct
回调执行远程SLSB查找并缓存所获得的代理:蜻蜓8:ejb远程代理线程安全吗?
@ApplicationScoped
@Typed({ ServiceInterface.class })
public class RemoteServiceProxy implements ServiceInterface
{
/**
* Remote service.
*/
private RemoteService remoteService;
/**
* Default constructor.
*/
public RemoteServiceProxy()
{
super();
}
/**
* PostConstruct callback.
*
* @throws RuntimeException
* Error while looking up remote proxy
*/
@PostConstruct
protected void onPostConstruct()
{
try
{
remoteService = serviceLocator.lookup(ActivityRemoteEntityService.class);
Properties jndiProps = new Properties();
jndiProps.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
jndiProps.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");
jndiProps.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
jndiProps.put("jboss.naming.client.ejb.context", "true");
Context context = new InitialContext(jndiProps);
remoteService = (RemoteService) context.lookup(
"application.backend/application.backend-service//RemoteServiceImpl!com.application.remote.RemoteService");
} catch (NamingException e)
{
throw new RuntimeException(e);
}
}
...
}
我想知道,如果缓存代理中字段remoteService
是线程安全的,因此RemoteServiceProxy
可以使用@ApplicationScoped
进行注释,或者我必须为每个调用执行一次新的代理查找?或者最好使用@Stateless
?
在此先感谢
答
的EJB 3.2规范有以下说:
3.4.9到Session Bean的并发访问参考
它是允许获取会话bean和参考尝试从多个线程同时调用同一个引用对象。但是,每个线程上产生的客户端行为取决于目标bean的并发语义。有关会话bean的并发行为的详细信息,请参见第4.3.13节和第4.8.5节。
§4.3.13基本上说会话bean的并发调用将被容器序列化。
§4.8.5描述了对Singleton会话Bean的并发访问的语义。
因此,为了符合远程代理的需要,必须具有固有的线程安全性,因为它必须遵循“会话bean引用”所需的语义。也就是说,如果你在EJB中存储了这样一个引用,那么这个引用将永远只能同时处理一个方法调用(因为这样的调用是“序列化的”)。这可能会导致应用程序出现不良的瓶颈。
感谢您的回答,我的疑问是,如果可以安全地将野蝇代理引用存储在同时访问的单一bean(CDI ApplicationScoped)中,换句话说,野蝇代理实现是线程安全的? – landal79
我已将更多信息添加到答案 –
它不是控制并发的@Singleton,它是会话bean。一个会话bean引用(您的代理)=>一个会话bean实例 –