【问题标题】:How to inject ApplicationContext in JAX-RS如何在 JAX-RS 中注入 ApplicationContext
【发布时间】:2015-06-28 11:46:42
【问题描述】:

我正在使用 Spring 和 JAX-RS 编写一个 Web 服务,但我对以下内容有点困惑

这是我的服务示例

@Path("/users")
public class UserService {

    @GET
    @Path("{id}")
    @Produces("application/xml")
    public User getById(@PathParam("id") int id) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        UserDAO userDAO = (UserDAO) context.getBean("userDao");
        return userDAO.getById(id);
    }

}

这是我的 beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <!-- Initialization for data source -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/hospital-system"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>

    <bean id="userDao" class="dao.UserDAO">
        <property name="dataSource" ref="dataSource"/>
    </bean>

</beans>

我想知道这是否是每次调用资源时加载应用程序上下文的正确技术,如果不是,我应该如何更改它?

【问题讨论】:

  • 您使用的是什么 JAX-RS 实现和版本?
  • jax-rs 如下 javax.ws.rsjsr311-api1.1.1
  • 和 jersey server 1.2
  • this。您应该能够只 @Autowired 服务(不需要上下文)。根据需要将依赖的版本更改为 1.2(因为本教程使用较新的版本。我认为它应该仍然适用于旧版本)

标签: java spring web-services jax-rs


【解决方案1】:

Jersey参考手册describes如何与Spring集成详细:

Jersey 提供了一个扩展来支持 Spring DI。这使 Jersey 能够将 Spring bean 用作 JAX-RS 组件(例如资源和提供程序),并且还允许 Spring 注入 Jersey 托管组件。

Spring 扩展模块配置是基于注解的。注入 Spring bean 并使用注解使 JAX-RS 类成为 Spring 管理。注入的 Spring bean 可以使用 Spring XML 配置注入更多的依赖项。支持 Spring 单例和请求范围。

要使 JAX-RS 资源能够使用需要代理的 Spring 功能,例如 Spring 事务管理(使用 @Transactional)、Spring Security 和面向方面的编程(例如 @Aspect),资源本身必须由 Spring 管理,通过使用@Component、@Service、@Controller 或@Repository 进行注释:

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import org.springframework.stereotype.Component;

@Component
@Path("/")
public class SomeResource {

    @Transactional
    @GET
    public void updateResource() {
        // ...
    }
}

限制:

  • 无法使用 Spring XML 配置将 Spring bean 直接注入到 JAX-RS 类中

依赖关系

如果您想使用 Jersey Spring DI 支持,您需要将 jersey-spring3 模块添加到依赖项列表中:

<dependency>
    <groupId>org.glassfish.jersey.ext</groupId>
    <artifactId>jersey-spring3</artifactId>
    <version>2.18</version>
</dependency>

上面的模块添加了对 Spring 模块的传递依赖。有关依赖项列表和范围的更多详细信息,请参阅 jersey-spring3 模块依赖项。请注意,该模块依赖于用于将 Spring 服务注入 HK2 服务或将 HK2 服务注入 Spring 服务的 Spring/HK2 桥接器。

要查看 Jersey 中 Spring DI 支持的示例,请参阅 Spring DI Example

【讨论】:

【解决方案2】:

每次调用此方法时创建应用程序工厂实例绝对不是一个好方法,

由于此方法可能会被调用 100 次,因此我们不希望创建此上下文 100 次,因为它不会发生任何变化。

你可以实现ApplicationContextAware接口

你可以做到

ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

在其他地方,也许当您的应用程序启动时。

希望这会有所帮助!

祝你好运!

【讨论】:

  • 它是否也会在其他服务之间共享相同的上下文?
  • 是的,如果它在你的应用程序启动时定义并且你只在你使用它的地方自动装配它,上下文将被整个应用程序中的服务共享
  • @Autowired 仅适用于 spring 创建的对象。默认情况下,Jersey 不使用 Spring 来创建资源对象。
猜你喜欢
  • 2017-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-21
  • 1970-01-01
  • 2019-08-10
  • 2013-04-24
相关资源
最近更新 更多