如何让 spring 管理 bean 生命周期而不是 jersey
how to have spring manage bean lifecycle instead of jersey
我在 tomcat 8 上使用 jersey 2.17,我对我认为应该是一个非常简单和常见的用例有疑问。
我在 spring XML 文件中定义了各种 bean。我现在已经注释了其中一个以将一些方法公开为 rest API。这是一个单例 bean,引用了 spring XML 配置中注入的另一个 bean。
我的其余 API 工作正常,但问题是每次调用时都会创建一个新的 bean 实例 class,而我的 bean 引用为空。我的理解是,这是因为 jersey 正在管理生命周期而不是 spring,我需要 SpringComponentProvider,它将提供单例。
我在我的应用中包含了jersey-spring3-2.17.jar,我在web.xml中的servlet配置中指定了spring包,如下:
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>
org.glassfish.jersey.servlet.ServletContainer
</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>my.rest.package;org.glassfish.jersey.server.spring</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.tracing.type</param-name>
<param-value>ALL</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
我知道 jersey.config.server.provider.packages 参数正在被提取,因为 my.rest.package 中带注释的 class 被找到,但是 SpringComponentProvider 显然没有被注册,因为我仍然每次都获取我的 bean 的新实例。
我尝试像这样明确指定 class:
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.server.spring.SpringComponentProvider</param-value>
</init-param>
这也没有改变行为。
任何见解或调试建议表示赞赏。
更新:我意识到我的 spring 罐子版本落后于我的球衣罐子预期的版本,我认为这就是问题所在。一旦我能够更新 spring,如果修复了它,我将关闭它。
Jersey 将在每次调用时创建一个新实例,无论您是否具有与 spring 上下文中的单例相同 class 的 XML bean:
https://jersey.java.net/documentation/latest/jaxrs-resources.html#d0e2331
另请参阅有关如何更改该行为的回复:
在你的 Jersey 资源 class 中,因为你已经添加了 jersey-spring 依赖,你可以简单地在你的成员变量上添加 @Autowire
注释,你说是通过XML 文件在 spring 中。这将 spring-在 Jersey 在每个请求上实例化资源时注入依赖项。
希望这对您有所帮助。
当我终于能够更新我的 spring 时,事实证明这不是问题所在。我必须将 @Component
和 @Singleton
添加到我的资源中,以便球衣将其识别为 spring 管理的单例。如果我对 spring 使用注解,这个问题就永远不会出现;发生这种情况是因为我正在使用 XML 创建 spring bean。
我在 tomcat 8 上使用 jersey 2.17,我对我认为应该是一个非常简单和常见的用例有疑问。
我在 spring XML 文件中定义了各种 bean。我现在已经注释了其中一个以将一些方法公开为 rest API。这是一个单例 bean,引用了 spring XML 配置中注入的另一个 bean。
我的其余 API 工作正常,但问题是每次调用时都会创建一个新的 bean 实例 class,而我的 bean 引用为空。我的理解是,这是因为 jersey 正在管理生命周期而不是 spring,我需要 SpringComponentProvider,它将提供单例。
我在我的应用中包含了jersey-spring3-2.17.jar,我在web.xml中的servlet配置中指定了spring包,如下:
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>
org.glassfish.jersey.servlet.ServletContainer
</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>my.rest.package;org.glassfish.jersey.server.spring</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.tracing.type</param-name>
<param-value>ALL</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
我知道 jersey.config.server.provider.packages 参数正在被提取,因为 my.rest.package 中带注释的 class 被找到,但是 SpringComponentProvider 显然没有被注册,因为我仍然每次都获取我的 bean 的新实例。
我尝试像这样明确指定 class:
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.server.spring.SpringComponentProvider</param-value>
</init-param>
这也没有改变行为。
任何见解或调试建议表示赞赏。
更新:我意识到我的 spring 罐子版本落后于我的球衣罐子预期的版本,我认为这就是问题所在。一旦我能够更新 spring,如果修复了它,我将关闭它。
Jersey 将在每次调用时创建一个新实例,无论您是否具有与 spring 上下文中的单例相同 class 的 XML bean:
https://jersey.java.net/documentation/latest/jaxrs-resources.html#d0e2331
另请参阅有关如何更改该行为的回复:
在你的 Jersey 资源 class 中,因为你已经添加了 jersey-spring 依赖,你可以简单地在你的成员变量上添加 @Autowire
注释,你说是通过XML 文件在 spring 中。这将 spring-在 Jersey 在每个请求上实例化资源时注入依赖项。
希望这对您有所帮助。
当我终于能够更新我的 spring 时,事实证明这不是问题所在。我必须将 @Component
和 @Singleton
添加到我的资源中,以便球衣将其识别为 spring 管理的单例。如果我对 spring 使用注解,这个问题就永远不会出现;发生这种情况是因为我正在使用 XML 创建 spring bean。