如何使用CDI传播相同的实例

时间:2017-01-23 01:21:47

标签: java ejb jax-rs cdi

我有一个带有JAX-RS,CDI和EJB的Web应用程序。在每个资源中,我注入一个无状态SessionBean,我的问题是是否可以将相同的实例注入JAX-RS和Stateless SesionBean的提供者。我试图从ContainerRequestFilter传递每个请求中的一些数据到Stateless SesionBean。所有EJB组件只能由jax rs resources访问。

示例:

public class Bean {
    private String attr;

    // getter and setter
}

@Stateless
public class BeanService {

    @Inject
    Bean bean;

    public void doStuff() {
        bean.getAttr();
        // do something with bean.attr
    }
}

@Path("/bean")
public class BeanResource {

    @Inject
    BeanService service;

    @GET
    public void doStuff() {
        service.doStuff():
    }
}

@Provider
public class BeanRequestFilter implements ContainerRequestFilter {

    @Inject
    Bean bean;

    @Override
    public void filter(ContainerRequestContext containerRequestContext) throws IOException {
        String data = null; // <- get data from request
        bean.setAttr(data);
    }
}

更新

更改Bean for Pojo,我的唯一目的是使用一个包含每个请求中的某个状态的类,并且可以在每个调用中传输,因为PojoResource到PojoService。我想以这种方式做到这一点,因为所有服务都会检索这些数据,我不希望将它作为参数传递给每个方法。

3 个答案:

答案 0 :(得分:0)

如果您希望Bean成为使用CDI的单身人士,请参阅@ApplicationScoped annotation(在这种情况下Bean应为Sersializable)< / p>

或者,如果您希望EJB BeanService成为单身,请参阅@Singleton annotation

答案 1 :(得分:0)

这似乎是您的Bean类本质上是请求作用域,因此将其更改为:

@RequestScoped
public class Bean {
    ...
}

应具有所需的效果。同一个实例将同时注入BeanRequestFilterBeanService

但是,我认为您可以通过将ContainerRequestContext直接注入BeanService并完全忘记Bean来获得您正在寻找的内容。

@Stateless
public class BeanService {

   @Context
   ContainerRequestContext containerRequestContext;

   public void doStuff() {
      // <- get data from request
   }
}

答案 2 :(得分:0)

在回答问题之前,Bean永远不应该更新。 bean的概念是提供服务并使用数据处理请求的概念。

也就是说,您当然可以将数据作为bean提供,但是数据需要在一个点上生成才能使用,而不是更新。

因此我会使用BeanRequestFilter来生成bean,让BeanService注入生成的bean。

尽管如此,我发现这是一个基于请求的数据?它是一个标题数据?,请求参数?然后我建议你在jax-rs资源类中使用jax-rs @QueryParam@HeaderParam@PathParam@FormParam@CookieParam,然后将数据作为域对象参数提供给BeanService,因此:

@Path("/api/resource-path")
public class MyResource {

    public void processSomething(@QueryParam("qparam") String param,  @HeaderParam("hparam") String hParam) {
        MyDomain domain = new MyDomain(qParam, hParam);
        myService.process(domain);
    }
}