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.