简体   繁体   中英

Jersey RESTful: Spring bean creation management

I have the following Jersey RESTful web service class to serve the HTTP request/response:

@Path("/customer")
public class CustomerService {

    private static ApplicationContext context;
    public static CustomerJDBCTemplate dbController;

    static {
        context = new ClassPathXmlApplicationContext("beans.xml");
        dbController = (CustomerJDBCTemplate) context.getBean("customerJDBCTemplate");
    }

        //methods for GET/POST requests ...
}

Here I use the static variable dbController as my DAO object. Since I want to have only one instance of dbController in my application, I give it a static property so that all Jersey classes can share the same dbController instance. So for example, if I have another Jersey class that uses a DAO, then I can just use it as CustomerService.dbController.create() and something like that. But I wonder if this is the correct and most appropriate way to instantiate a DAO bean inside a Jersey class because if the resource at Path: /customer is not called, then the DAO bean is not instantiated.

I can also repeat the above bean instantiation steps in another Jersey class:

@Path("/another")
public class AnotherService {

    private static ApplicationContext context;
    public static  CustomerJDBCTemplate dbController;

    static {
        context = new ClassPathXmlApplicationContext("beans.xml");
        dbController = (CustomerJDBCTemplate) context.getBean("customerJDBCTemplate");
    }

        //methods for GET/POST requests ...
}

My question is: Will this create a different instance than the first one? Or are CustomerService.dbController and AnotherService.dbController refer to the same object?

If I want to use the first DAO object CustomerService.dbController in a non-Jersey class (eg, service layer classes), should I use the first method to create the bean only in one Jersey class as a public static variable and refer it in all classes that use dbController ? What is the best practice here?

The best practice is to use @ Inject instead of static . Jersey has its own injection mechanism

public class MyApplication extends ResourceConfig {
public MyApplication() {
    register(new FacadeBinder());

Register as Singleton

public class FacadeBinder extends AbstractBinder {

  @Override
  protected void configure() {
    bind(MyManager.class).to(MyManager.class);
  }
}

Then in your resource endpoint you can use registered classes:

@Path("/jersey")
public class MyEndpoint implements MyInterface {
  @Inject
  MyManager myManager;

Or you can integrate with some other injection framework such as Guice or Spring.

First, if you plan to use Jersey+Spring, I think the jersey-spring integration is worth checking out .

Also, the whole point of using any Dependency Injection/Inversion Of Control framework is to manage the lifecycle and inter-dependency of "beans". DI/IoC libs and frameworks are here t avoid this static/dependency nightmare and to help you build testable, extensible applications.

This part of the Spring reference documentation should make things clearer. By default , Spring creates and manages singleton beans for you (one instance shared by all within your application). Check out the beans scopes documentation .

General rule of thumb: injecting/using directly the application context is somewhat of a code smell (especially if you hardcode the name of your context file!).

If you're looking for best practices, the Jersey+Spring example should help you .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM