为什么不只使用一个无状态bean和一个远程接口?
远程 bean 的一个非常好的特性是,它们可以是通用的,所以基本上你只需要一个接口和一个远程 bean(参见 SimpleEntity 及其远程 bean)。
我混合使用了一个非常通用的远程 bean DAO 来读取简单的实体和一些特定的 bean,用于需要更多 CUD 操作逻辑的实体。接下来我只是提取了最小接口来重现它。
如果我创建一个新表和实体,它可以立即在远程客户端上使用。
实体
/*
* Complex entity with enhanced CRUD logic
*/
public class Foo implements Entity { }
/*
* Simple entity without complex CRUD logic
*/
public class Bar implements SimpleEntity { }
界面
public interface Entity { }
public interface SimpleEntity extends Entity { }
/*
* Generic entity DAO interface, for remote beans and other datasources
*/
public interface IEntityDAO<T extends Entity>
{
public T get(Class<T> type, long id);
public T update(T t);
}
/*
* Generic remote bean interface for a JNDI service locator lookup
*/
public interface EntityDAOBeanRemote<T extends Entity> extends IEntityDAO<T> { }
无状态远程 Bean
/*
* 'abstract' base class for stateless DAO beans
*/
public class AEntityDAOBean<T extends Entity> implements EntityDAOBeanRemote<T>
{
public T get(Class<T> type, long id)
{
Session session = // obtain current hibernate session
return id == (T) session.createCriteria(type).add(Restrictions.idEq(id)).uniqueResult();
}
public T update(T t, long id)
{
Session session = // obtain current hibernate session
session.update(t);
return t; // return updated instance
}
}
/*
* Generic stateless remote DAO bean implementation
*/
@Stateless(mappedName = "SimpleEntityDAOBean")
@Remote(EntityDAOBeanRemote.class)
public class SimpleEntityDAOBean extends AEntityDAOBean<SimpleEntity> implements EntityDAOBeanRemote<SimpleEntity>
{
// empty since all methods are from parent class
}
/*
* Foo specific remote DAO bean
*/
@Stateless(mappedName = "FooDAOBean")
@Remote(EntityDAOBeanRemote.class)
public class FooDAOBean extends AEntityDAOBean<SimpleEntity> implements EntityDAOBeanRemote<Foo>
{
@Override
public Foo update(Foo foo)
{
// make specific foo things and update
return foo;
}
}
客户
在您的客户端使用 JNDI,您可以使用 JNDI 服务定位器模式调用 bean,例如:
EntityDAOBeanRemote<Foo> fooDAOBeanRemote = jndiServiceLocator
.getEntityDAOBeanRemote(Foo.class);
EntityDAOBeanRemote<Bar> barDAOBeanRemote = jndiServiceLocator
.getEntityDAOBeanRemote(Bar.class);
客户端 JSF
借助通用 JSF 转换器和用于 GUI 框架的 DAO 通用扩展(例如 PrimeFaces LazyDataModel),它可以节省大量时间,使新实体可以在 JSF bean 中快速访问并在 GUI 中进行编辑。