Wildfly 8:ejb远程代理线程安全吗?
Wildfly 8: are ejb remote proxy thread safe?
我有以下情况,在客户端 ear 应用程序中有 CDI @ApplicationScoped
bean,它在 @PostConstruct
回调上执行远程 SLSB 查找并缓存获得的代理:
@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 对会话 Bean 引用的并发访问
允许获取会话 bean 引用并尝试从多个线程并发调用同一引用对象。但是,每个线程上的最终客户端行为取决于目标 bean 的并发语义。有关会话 bean 的并发行为的详细信息,请参阅第 4.3.13 节和第 4.8.5 节。
§4.3.13 基本上说对会话 bean 的并发调用将由容器序列化。
§4.8.5 描述了并发访问 Singleton Session bean 的语义。
因此,为了符合要求,远程代理需要本质上是线程安全的,因为它必须遵循 "session bean reference".
所需的语义。
就是说,如果您将这样的引用存储在 @Singleton
EJB 中,那么该引用一次只能同时处理一个方法调用(因为这样的调用是 "serialized").这可能会导致您的应用程序出现不良瓶颈。
我有以下情况,在客户端 ear 应用程序中有 CDI @ApplicationScoped
bean,它在 @PostConstruct
回调上执行远程 SLSB 查找并缓存获得的代理:
@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 对会话 Bean 引用的并发访问
允许获取会话 bean 引用并尝试从多个线程并发调用同一引用对象。但是,每个线程上的最终客户端行为取决于目标 bean 的并发语义。有关会话 bean 的并发行为的详细信息,请参阅第 4.3.13 节和第 4.8.5 节。
§4.3.13 基本上说对会话 bean 的并发调用将由容器序列化。
§4.8.5 描述了并发访问 Singleton Session bean 的语义。
因此,为了符合要求,远程代理需要本质上是线程安全的,因为它必须遵循 "session bean reference".
所需的语义。就是说,如果您将这样的引用存储在 @Singleton
EJB 中,那么该引用一次只能同时处理一个方法调用(因为这样的调用是 "serialized").这可能会导致您的应用程序出现不良瓶颈。