3

I am writing a web service using Spring and JAX-RS, and I'm kinda confused with the following

Here's my service exmaple

@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);
    }

}

And here's my 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>

I wonder if this is the right technique to load Application context each time the resource get's called, and if no, how should I change it?

vcmkrtchyan
  • 2,536
  • 5
  • 30
  • 59

2 Answers2

3

The Jersey reference manual describes how to integrate with Spring in detail:

Jersey provides an extension to support Spring DI. This enables Jersey to use Spring beans as JAX-RS components (e.g. resources and providers) and also allows Spring to inject into Jersey managed components.

The Spring extension module configuration is based on annotations. Spring beans are injected and JAX-RS classes are made Spring managed using annotations. Injected Spring beans can have further dependencies injected using Spring XML configuration. Spring singleton and request scopes are supported.

To enable JAX-RS resources to work Spring functionality that requires proxying, such as Spring transaction management (with @Transactional), Spring Security and aspect oriented programming (such as @Aspect), the resources must themselves be managed by Spring, by annotating with @Component, @Service, @Controller or @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() {
        // ...
    }
}

Limitations:

  • Spring beans can't be injected directly into JAX-RS classes by using Spring XML configuration

Dependencies

If you want to use Jersey Spring DI support you will need to add the jersey-spring3 module into the list of your dependencies:

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

The above module adds transitive dependencies on Spring modules. See jersey-spring3 module dependencies for more details about list and scope of dependencies. Please note the module depends on The Spring/HK2 Bridge that is used to inject Spring services into HK2 services or inject HK2 services into Spring services.

To see an example of Spring DI support in Jersey refer to the Spring DI Example.

meriton
  • 68,356
  • 14
  • 108
  • 175
2

Creating the application factory instance everytime when a web service call is made to this method is definitely, not a good approach ,

as this method might get called maybe say 100 times, we do not want to have a over head of creating this context 100 times as nothing is going to change in it.

you may implement the ApplicationContextAware interface

and you can do

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

at some other place , maybe when your application starts up.

hope this helps!

Good luck!

Community
  • 1
  • 1
Vihar
  • 3,626
  • 2
  • 24
  • 47
  • will it also share the same context between other services? – vcmkrtchyan Jun 28 '15 at 12:20
  • Yes , if its defined when your application starts up and you only autowire it in the places you use it, the context will be shared by services in entire application – Vihar Jun 28 '15 at 12:22
  • @Autowired only works in objects created by spring. By default, Jersey does not use Spring to create resource objects. – meriton Jun 28 '15 at 14:50