mar*_*n72 1 java service servlets
假设我想为我的使用 servlet 的 web 应用程序创建一个服务层,我应该怎么做?(我没有使用 web 应用程序框架..所以,请耐心等待)。我应该将它实现为侦听器吗?该服务旨在进行数据库访问。也就是说,我应该能够从我的 servlet 调用
class MyServlet{
...
doPost(...){
...
MyEntity entity = dbAccessService.getMyEntity(someId);
...
}
}
Run Code Online (Sandbox Code Playgroud)
dbAccessService 应该在哪里处理休眠会话、事务等。以前我曾经在 dao 方法中完成所有这些,但我被告知这不是一个好主意。
欢迎任何建议
谢谢
标记
下面给出了示例代码片段
class DBAccessServiceImpl{
...
private MyEntity getMyEntity(Long id){
Transaction tx = null;
MyEntity me = null;
Session session = HibernateUtil.getCurrentSession();
try{
tx = session.beginTransaction();
return entitydao.findEntityById(id);
}catch(RuntimeException e){
logger.info("problem occurred while calling findEntityById()");
throw e;
}
}
...
}
Run Code Online (Sandbox Code Playgroud)
然后创建一个监听器来实例化DBAccessService
class MyAppListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent ctxEvent) {
ServletContext sc = ctxEvent.getServletContext();
DBAccessService dbservice = new DBAccessServiceImpl();
sc.setAttribute("dbAccessService",dbservice);
}
}
Run Code Online (Sandbox Code Playgroud)
在 web.xml 添加监听器
...
<listener>
<listener-class>myapp.listeners.MyAppListener</listener-class>
</listener>
...
Run Code Online (Sandbox Code Playgroud)
假设您不想引入框架,有两个选项是有意义的(在我看来):
定义一个接口
public interface BusinessService {
abstract public BusinessObject performSomeOperation(SomeInput input);
}
Run Code Online (Sandbox Code Playgroud)
和一个实现
public class BusinessServiceImpl implements BusinessService {
public BusinessObject performSomeOperation(SomeInput input) {
// some logic here...
}
}
Run Code Online (Sandbox Code Playgroud)
您有多种选项可用于实例化服务。如果您从头开始使用一个小型应用程序,那么在您的 Web 应用程序中简单地实例化服务可能就足够了:
BusinessService service = new BusinessServiceImpl();
service.performSomeOperation(...);
Run Code Online (Sandbox Code Playgroud)
顺便说一句:稍后您可能想要重构和实现一些围绕服务实例化的抽象(工厂模式、依赖注入等)。此外,在大型系统中,您可能必须将服务层托管在其自己的基础架构上以实现可扩展性,以便您的 web 应用程序通过开放协议与服务层通信,无论是 RESTful 还是 Web 服务。
然而,未来看起来,如果应用程序增长,拥有定义业务功能的定义良好的接口将允许您“轻松”向前推进。
对您的更新的回应:
我不会将服务本身实现为侦听器,这是没有意义的。尽管如此,您的示例代码似乎是合理的,但您必须区分Service(在本例中DBAccessService)和实例化/检索它的方式(侦听器)。您实现的侦听器实际上扮演了能够查找特定服务的ServiceLocator的角色。如果您将服务的实例存储在 servlet 上下文中,您必须提醒服务实现必须是线程安全的。
你必须小心不要过度设计你的设计——只要你不能预见到更复杂的需求,就保持简单。如果它还不复杂,我建议使用简单的静态工厂方法封装实现:
public final class ServiceFactory {
public static DBAccessService getDBAccessService() {
DBAccessService service = new DBAccessServiceImpl();
return service;
}
}
Run Code Online (Sandbox Code Playgroud)
可以使用复杂的替代方案来实现ServiceFactory,现在有些人称之为反模式。但是只要您不想从依赖注入(等)开始,这仍然是一个有效的解决方案。服务实现DBAccessServiceImpl只能在一个地方(工厂)访问。正如我之前提到的 - 密切关注多线程......希望这会有所帮助!
| 归档时间: |
|
| 查看次数: |
3022 次 |
| 最近记录: |