Dropwizard多层应用程序

时间:2018-04-10 13:36:48

标签: rest dependency-injection dropwizard multi-layer

我有简单的 Dropwizard 休息服务应用程序,它只有两层: 控制器层 (又名资源)和 持久层 (又名dao)。 Dropwizard应用程序小而简洁,工作顺利。

然而,在一些需求发生变化之后,我需要添加一些业务逻辑来处理传入的json对象,然后将其持久化到数据库中。所以,我正在寻找在控制器和持久层之间添加 服务层 的最佳方法。

请您建议在应用程序中添加服务层的最佳方法。感谢。

控制器(又名资源):

@Path("/person")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public class PersonResource {

   private PersonService personService;

   public PersonResource(PersonService personService) {
        this.personService = personService;
    }


   @GET
    public List<Person> getAll(){
        return personService.getAll();
    }

   @GET
    @Path("/{id}")
    public Person findById(@PathParam("id") Integer id){
        return personService.findPersonById(id);
    }
}

服务层:

public class PersonService {

   private PersonDAO personDAO;

   public PersonService(PersonDAO personDAO) {
        this.personDAO = personDAO;
    }

   @UnitOfWork
    public List<Person> getAll(){
        return personDAO.getAll();
    }

   @UnitOfWork
    public Person findPersonById(Integer id){
        return personDAO.findById(id);
    }
}

申请类:

public class DemoApplication extends Application<DemoConfiguration> {

   public static void main(final String[] args) throws Exception {
        new DemoApplication().run(args);
    }

   private final HibernateBundle<DemoConfiguration> hibernateBundle = new HibernateBundle<DemoConfiguration>(Person.class) {
        @Override
        public DataSourceFactory getDataSourceFactory(DemoConfiguration configuration) {
            return configuration.getDatabaseAppDataSourceFactory();
        }
    };

   @Override
    public void initialize(final Bootstrap<DemoConfiguration> bootstrap) {
        bootstrap.addBundle(hibernateBundle);
    }

   @Override
    public void run(final DemoConfiguration configuration, final Environment environment) {
        final PersonDAO personDAO = new PersonDAO(hibernateBundle.getSessionFactory());
        final PersonService personResource = new PersonService(personDAO);
        environment.jersey().register(personResource);
    }
}

我可以成功启动应用程序但是当涉及处理请求时,它会失败404错误代码。在日志中看到这条消息:

org.glassfish.jersey.internal.inject.Providers:在SERVER运行时中注册的提供程序com.laboratory.dropwizard.service.PersonService未实现适用于SERVER运行时的任何提供程序接口。由于约束      配置问题提供程序com.laboratory.dropwizard.service.PersonService将被忽略。

Dropwizard有什么问题,我该如何介绍工作服务层? 感谢。

2 个答案:

答案 0 :(得分:1)

您正在尝试register PersonService,因此您收到错误(警告)。 register方法仅用于注册资源和已知提供程序类型。您可能想要做的是使用依赖注入。你要做的是将DAO和服务绑定到注入框架。然后你可以使用@Inject在需要的地方注入它们。

@Override
public void run(DemoConfiguration conf, Environment env) {
    env.jersey().register(new AbstractBinder() {
        @Override
        public void configure() {
            bindAsContract(PersonDAO.class).in(Singleton.class);
            bindAsContract(PersonService.class).in(Singleton.class);
        }
    });
}

现在,您可以将DAO注入服务,将服务注入资源

public class PersonService {
    private PersonDAO dao;

    @Inject
    public PersonService(PersonDAO dao){
        this.dao = dao;
    }
}

@Path("people")
public class PersonResource {
    private PersonService service;

    @Inject
    public PersonResource(PersonService service) {
        this.service = service;
    }
}

答案 1 :(得分:0)

From the documentation

  

目前使用@UnitOfWork注释创建交易仅对泽西岛管理的资源开箱即用。如果您想在Jersey资源之外使用它,例如在身份验证器中,您应该使用UnitOfWorkAwareProxyFactory实例化您的课程。

说明这一点的代码示例是:

SessionDao dao = new SessionDao(hibernateBundle.getSessionFactory());
ExampleAuthenticator exampleAuthenticator = new UnitOfWorkAwareProxyFactory(hibernateBundle)
               .create(ExampleAuthenticator.class, SessionDao.class, dao);

沿着这条线尝试一下。