admin管理员组文章数量:1287626
I am trying to understand JAX-RS, CDI integration in Wildfly, specifically how the bean lifecycle looks like. The following behaviour is not what I expected. Below is drilled down example.
@Dependent
@Path("/users")
@Produces(MediaType.APPLICATION_JSON)
public class UserResourceImpl {
@PostConstruct
public void init() {
System.out.println("UserResourceImpl init ...");
}
@PreDestroy
public void destroy() {
System.out.println("UserResourceImpl destroy ...");
}
@GET
public Response test() {
return Response.ok("{ \"answer\": \"working...\"}").build();
}
}
Simple REST resource implementation with @Dependent scope. Why I am annotating this bean explicitly because my beans.xml is configured like that.
<?xml version="1.0" encoding="UTF-8"?>
<beans version="4.0"
xmlns="; xmlns:xsi=";
xsi:schemaLocation="
.xsd"
bean-discovery-mode="annotated">
</beans>
Bean discovery mode is annotated. This is on purpose, since I am studying bean lifecycle and wanted to keep things in my control.
So when this simple application is deployed in Wildfly 32 application server, what I notice is that @PostContruct is called for each HTTP request being received. Even after I already see the response on the client application i.e. HTTP request is completed, @PreDestroy never get called. Even when application is terminated, @PreDestroy does not get called. Why?
Looking at the documentation from RESTEasy /6.2/userguide/#_default_scopes
A CDI bean that does not explicitly define a scope is @Dependent scoped by default. This pseudo scope means that the bean adapts to the lifecycle of the bean it is injected into. Normal scopes (request, session, application) are more suitable for Jakarta RESTful Web Services components as they designate component’s lifecycle boundaries explicitly. Therefore, the resteasy-cdi module alters the default scoping in the following way:
If a Jakarta RESTful Web Services root resource does not define a scope explicitly, it is bound to the Request scope.
If a Jakarta RESTful Web Services Provider or jakarta.ws.rs.Application subclass does not > define a scope explicitly, it is bound to the Application scope.
So I expect this to behave like @RequestScoped bean, calling both @PostConstruct and @PreDestroy for each completed HTTP request.
Could someone explain this to me? Is this a Bug?
I am trying to understand JAX-RS, CDI integration in Wildfly, specifically how the bean lifecycle looks like. The following behaviour is not what I expected. Below is drilled down example.
@Dependent
@Path("/users")
@Produces(MediaType.APPLICATION_JSON)
public class UserResourceImpl {
@PostConstruct
public void init() {
System.out.println("UserResourceImpl init ...");
}
@PreDestroy
public void destroy() {
System.out.println("UserResourceImpl destroy ...");
}
@GET
public Response test() {
return Response.ok("{ \"answer\": \"working...\"}").build();
}
}
Simple REST resource implementation with @Dependent scope. Why I am annotating this bean explicitly because my beans.xml is configured like that.
<?xml version="1.0" encoding="UTF-8"?>
<beans version="4.0"
xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3./2001/XMLSchema-instance"
xsi:schemaLocation="
https://jakarta.ee/xml/ns/jakartaee
https://jakarta.ee/xml/ns/jakartaee/beans_4_0.xsd"
bean-discovery-mode="annotated">
</beans>
Bean discovery mode is annotated. This is on purpose, since I am studying bean lifecycle and wanted to keep things in my control.
So when this simple application is deployed in Wildfly 32 application server, what I notice is that @PostContruct is called for each HTTP request being received. Even after I already see the response on the client application i.e. HTTP request is completed, @PreDestroy never get called. Even when application is terminated, @PreDestroy does not get called. Why?
Looking at the documentation from RESTEasy https://docs.resteasy.dev/6.2/userguide/#_default_scopes
A CDI bean that does not explicitly define a scope is @Dependent scoped by default. This pseudo scope means that the bean adapts to the lifecycle of the bean it is injected into. Normal scopes (request, session, application) are more suitable for Jakarta RESTful Web Services components as they designate component’s lifecycle boundaries explicitly. Therefore, the resteasy-cdi module alters the default scoping in the following way:
If a Jakarta RESTful Web Services root resource does not define a scope explicitly, it is bound to the Request scope.
If a Jakarta RESTful Web Services Provider or jakarta.ws.rs.Application subclass does not > define a scope explicitly, it is bound to the Application scope.
So I expect this to behave like @RequestScoped bean, calling both @PostConstruct and @PreDestroy for each completed HTTP request.
Could someone explain this to me? Is this a Bug?
Share Improve this question edited Feb 26 at 7:44 office.aizaz asked Feb 23 at 14:18 office.aizazoffice.aizaz 3031 silver badge13 bronze badges 8 | Show 3 more comments1 Answer
Reset to default 1Minor nit, if you're using WildFly 32 you're using Jakarta REST 3.1.
By default RESTEasy uses @RequestScoped
for endpoints and @ApplicationScoped
for jakarta.ws.rs.core.Application
's and providers.
Since you defined @Dependent
, you're effectively saying "give me a new bean each time" as you're not injecting that Jakarta REST resource into another scoped bean. As to why the bean is not being destroyed, I'm not sure yet. The JavaDoc is a bit odd IMO.
When the container destroys an instance of a bean or of any Java EE component class supporting injection, the container destroys all its dependent objects, after the @PreDestroy callback completes and after the servlet destroy() method is called.
While RESTEasy itself does support Servlet, there is no requirement in the Jakarta REST specification that a Servlet be used. I'll have to look into why the beans are not getting destroyed.
All this said, I do think @Dependent
is the wrong scope for a Jakarta REST endpoint and you're better to, at a minimum, use @RequestScoped
endpoints.
本文标签: jax rsCDI 40 Integration with Jakarta REST 31 in WildFly serverStack Overflow
版权声明:本文标题:jax rs - CDI 4.0 Integration with Jakarta REST 3.1 in WildFly server - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741315740a2371904.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
@Dependent
beans are a bit special and if you retrieve them outside of any other context, you also need to destroy them properly. That being said, why@Dependent
? I'd say@RequestScoped
is a much better fit for this? – Siliarus Commented Feb 24 at 8:58@RequestScoped
makes sense. Most of research I did on internet is also suggesting the same. I wanted to understand the relationship with HTTP requests and CDI beans. I understand how@Dependent
scoped beans utlimately adopt the scope of the beans where are being injected into. JAXRS resources for me are bit of mystery. They are not really CDI, so I wondered what happens if the resources are annotated. I guess, CDI simply cares for the annotated beans (in my case because of beans.xml) and is not aware of that same bean is also a JAXRS resource. – office.aizaz Commented Feb 24 at 13:45@RequestScoped
, who/how tells CDI to create this CDI bean and destroy it when request is completed? I guess JAX-RS (somehow). So in a way, this class is injected in JAXRS? :S – office.aizaz Commented Feb 24 at 17:05