I have a resource to be exposed as Restful WS.If I have to make it Singleton, what is the preferred and advised way:
1 . Annotating the resource class using #Singleton
Or
2 . Implementing the getSingletons() method in my Application class implementation and instantiating the resource there like
public class RestApplication extends Application {
private Set<Object> singletons = new HashSet<Object>();
public RestApplication() {
singletons.add(new PlayerResource());
}
#Override
public Set<Class<?>> getClasses() {
return null;
}
#Override
public Set<Object> getSingletons() {
return singletons;
}
}
I tried both ways and realised that both of them creates a singleton instance of the resource class, PlayerResource in this case.
For the most part, Everything technical you need to know has already been answered here.
For the rest of your answer, It doesn't really matter, as long as you are consistent throughout the code base.
The advantage of not using the annotation, is that if a module not provisioned by Jersey needs the resources, it will get the same singleton. (Like if you expect any third party plug-ins to interact with this resource)
The advantage to using the annotation is that you can let Jersey take care of the annoying/tedious stuff for you. (Like resource clean-up, if you use any close-able resources.)
Related
Consider the case where I have a Spring Service bean, which depends on other beans that may expose the AutoCloseable interface. I'll ask this question generically and will later explain my specific need.
public class ServiceBean {
#Autowired private ResourceBean resource; //Resource is Closeable
}
According to configuration, under certain configurations Resource is a global singleton, and in other cases it is a prototype. Since I am writing a library, I was asked to provide degrees of flexibility.
If resource is a singleton, it should never be close()d until the ApplicationContext is shut down. Otherwise, if resource was created prototypely for my instance of ServiceBean (which is a prototype, I know this by design), then it shall be disposed (close()d) when the lifecycle of ServiceBean ends.
Step 1: make ServiceBean closeable
Not a bad thing to do. Best practices in programming say that when your class depends on disposable resources, it should be declared disposable and included in try-with-resources blocks
public class ServiceBean implements AutoCloseable {
#Autowired private ResourceBean resource; //Resource is Closeable
public void close() throws Exception {
resource.close(); //what the!!!
}
}
The problem with this setup is that if resource is a prototype, it will be closed on first instance.
Spring provides methods isPrototype and isSingleton that take String as argument, so I deduce they are meant for bean names, which I don't (want) to know in this context
Question: what should be the correct way to dispose prototype resources in prototype beans? Spring AFAIK disposes only of singletons when ApplicationContext shuts down
My specific case
I have a ThreadPoolTaskExecutor to inject. It may be a singleton or prototype object, and the shutdown is useful to clear the pool from outstanding threads
I have come with an idea (a mad idea, not yet tested).
The injected resource bean could leverage the BeanFactory<> class.
Declare Resource by means of a factory
public class ResourceBeanFactoryBean extends AbstractFactoryBean
Parameterize the singletonness
AbstractFactoryBean exposes isSingleton
Wrap the returned bean into a non-closeable when the bean is singleton
protected ResourceBean createInstance() {
return isSingleton() ? myBean : wrapNonCloseable(myBean);
}
Where myBean is the instance you would have created normally, and wrapNonCloseable is a utility method that extends the close method to do nothing
protected MyResourceBean wrapNonCloseable(MyResourceBean bean) {
return new MyResourceBean()
{
//Delegate all methods to the original bean
public void close(){}
}
}
I want to use a DAO in my RESTful service developed with Jersey, so the DAO implementation should be injected via the constructor of the service:
#Path("eventscheduler)
public class EventSchedulerService {
private IEventSchedulerDao dao;
public EventSchedulerService(IEventSchedulerDao dao) { this.dao = dao; }
}
However, I know Jersey expects a default constructor to setup everything correctly. I have been trying to figure out how to do this for a while but surprisingly this seems to be an uncommon case, I wonder how people inject DAOs into their services, or deal with injection in general at all.
How can I do this?
If you're using Jersey 2, it uses HK2 as it's DI framework. All resource classes go through the DI lifecycle when they are constructed. And constructor injection is not a problem.
The most basic way (with Jersey) to make an arbitrary object injectable, is to bind in an AbstractBinder
public class Binder extends AbstractBinder {
#Override
protected void configure() {
bind(EventSchedudlerDaoImpl.class).to(EventSchedulerDao.class);
}
}
Then register the binder with Jersey
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
register(new Binder());
}
}
Then you just need to declare the injection point by adding #Inject on top of the constructor.
#Inject
public EventSchedulerService(EventSchedulerDao dao) {
this.dao = dao;
}
As far as the binder implementation, the binding syntax basically reads as
bind( Implementation ).to( Contract ).in( Scope );
The bind method can take an instance or it can take a class. When you provide an instance, the Scope is automatically Singleton.
The to method specifies the advertised contract, which is the type that can be declared at the injection point. In this case, only the interface EventSchedulerDao can be used for the injection point. If you don't have an interface you can just do
bindAsContract(EventSchedulerDao.class)
assuming EventSchedulerDao is the implementation class.
The scopes available are PerLookup, RequestScoped and Singleton. If not specified, the default scope will be PerLookup, meaning a new instance of the service will be created for each injection point. You should already know what Singleton means. RequestScoped means that a new instance will be created for each request, which may not be the same as PerLookup, as the service may be injected at multiple points through out the request lifeclyle.
See Also:
Dependency injection with Jersey 2.0
Custom Injection and Lifecycle Management
hk2 tagged questions. Alot of them are Jersey related.
You must annotate the class constructor (or the property itself) with javax.inject.Inject.
import javax.inject.Inject;
class EventSchedulerResource {
private final IEventSchedulerDao dao;
#Inject
public EventSchedulerResource(IEventSchedulerDao dao) {
this.dao = dao;
}
// ...
}
If the IEventScheduler is an interface you must create a configuration class class that extends org.glassfish.jersey.server.ResourceConfig and register the binding of interface to a concrete implementation with bind(EventSchedulerDaoImpl.class).to(IEventScheduler.class) (See here: https://jersey.java.net/documentation/latest/ioc.html chapter 23.1)
I am planning to implement the Rest service with help of RestEasy framework (3.0.11) and servlet version 3.
I have used resteasy-scan context to scan my rest service at time of runtime, but since servlet version 3.0 hence It is not scan and throwing exception (deployed in tomcat7).
Could you please suggest me to resolve the issue, how to scan the rest services?
Any example or configuration of web.xml would be good.
One way, without any web.xml (RESTeasy servlet) configuration is to just have an empty Application subclass, annotated with #ApplicationPath (for the url-mapping).
According to the JAX-RS spec, in a Servlet 3.x environment if you have the following
#ApplicationPath("/api")
public class MyAppliation extends Application {
}
this is enough to cause the application to register resource class and provider through classpath scanning. In contrast, we could explicitly register resources class and providers this way
#ApplicationPath("/api")
public class MyAppliation extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(MyResource.class);
return classes;
}
#Override
public Set<Object> getSingletons() {
Set<Object> singletons = new HashSet<Object>();
singletons.add(new MyFilter());
return singletons;
}
}
According to the spec, once we return a non-empty set from either one of these overridden methods, it is assumed the application takes care of all the registration, and the classpath registration is disabled.
Now this is not what you want, but it is just a background as to why the empty class works.
I have a prototype storm app that reads a STOMP stream and stores the output on HBase. It works, but is not very flexible and I'm trying to get it set up in a more consistent way with the rest of our apps, but not having much luck figuring out how the current way of working with Storm. We use spring-jms classes, but instead of using them in the standard spring way, they are being created at run time, and setting dependencies manually.
This project: https://github.com/granthenke/storm-spring looked promising, but it hasn't been touched in a couple years and doesn't build properly since the storm jars have been taken into apache incubator and repackaged.
Is there something I'm missing, or is it not worth my while to get these things integrated?
#zenbeni has answered this question but I wanna tell you about my implementation, it's hard to make spouts/bolts as spring beans. But to use other spring spring beans inside your spouts/bolts you could declare a global variable & in your execute method check whtether variable is null or not. If it's null you have to get bean from application context. Create a class which contains a method to initialize beans if it's not initialized already. Look ApplicationContextAware interface for more information(Spring bean reuse).
Example Code:
Bolt Class:
public class Class1 implements IRichBolt{
Class2 class2Object;
public void prepare() {
if (class2Object== null) {
class2Object= (Class2) Util
.initializeContext("class2");
}
}
}
Util Class for initializing Beans if not initialized already:
public class Util{
public static Object initializeContext(String beanName) {
Object bean = null;
try {
synchronized (Util.class) {
if (ApplicationContextUtil.getAppContext() == null) {
ApplicationContext appContext = new ClassPathXmlApplicationContext("beans.xml");
bean = ApplicationContextUtil.getAppContext().getBean(
beanName);
} else {
bean = ApplicationContextUtil.getAppContext().getBean(
beanName);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return bean;
}
}
Listener for Application Context Change:
#Component
public class ApplicationContextUtil implements ApplicationContextAware {
private static ApplicationContext appContext;
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
appContext = applicationContext;
}
public static ApplicationContext getAppContext() {
return appContext;
}
}
Note: Each Worker will initialize spring context because it's running in different JVM.
UPDATE
If you want to use a spring bean class in which you have some values previously assigned try this,
Note: Passing the current class to Bolt's constructor
Class (Topology Creation Class) which is already contains values:
public class StormTopologyClass implements ITopologyBuilder, Serializable {
public Map<String, String> attributes = new HashMap<String, String>();
TopologyBuilder builder=new TopologyBuilder();
builder.setBolt("Class1",new Class1(this));
builder.createTopology();
}
Bolt by using single argument constructor:
public class Class1 implements IRichBolt{
StormTopologyClass topology;
public Class1 (StormTopologyClass topology) {
this.topology = topology;
}
}
Now you could use attributes variable & it's values in bolt class.
In fact, storm-spring seems to be what you are looking for but it is not updated and have limitations (cannot define tasks on bolts / spouts for instance, etc). Maybe you should roll your own integration?
Don't forget your target: a cluster with many workers. How does spring behave when you will deploy your topology with storm api (rebalance for instance) on one more worker? Does it mean it has to instanciate a new Spring context on the worker JVM at startup before Storm deploys the targeted bolts / spouts and defines the executors?
IMHO if you define only Storm components in a Spring configuration it should work (startup configuration for the topology then storm only manages the objects) but if you rely on Spring to manage other components (it seems so with spring-jms), then it could become messy on topology rebalances for instance (singleton per worker / jvm? Or the whole topology?).
It is up to you to decide if it is worth the trouble, my concern with a Spring configuration is that you easily forget the storm topology (it seems it is one JVM but can be many more). Personally I define my own singletons per class-loader (static final for instance or with double check locking if I need deferred instanciation), as it does not hide the (medium-high) complexity.
I realize that this is very after the fact, but did you think of using Apache camel for the JMS connection handling? Camel isn't IOC or DI, but it does model enterprise integration patterns. Maybe that's what you are (were?) looking for?
Nick.
Maybe this tutorial can help you.
http://spring.io/guides/gs/messaging-stomp-websocket/
I have a problem with injecting a bean into a helper class. It works basically like this: I create an object in the page constructor that does some work, returns some data and I show these on the page. In this helper object, a service should be injected via #Autowired annotation. However, I always get a null pointer exception when I use it. I also tried #SpringBean but it didn't help. On the other hand, when I inject this service directly into the page with #SpringBean, it's accessible and works fine. Do you know where the problem is?
This is the page:
public class Page extends BasePage {
public Page() {
HelperObject object = new HelperObject(new Application("APP_NAME"));
String result = object.getData();
add(new Label("label", result));
}
}
Helper object:
public class HelperObject {
private Application app;
#Autowired
private Service service;
public HelperObject(Application app) {
this.app = app;
}
public String getData() {
// use service, manipulate data, return a string
}
}
You can inject dependencies into non-Spring-non-Wicket-new-created objects using #SpringBean by calling InjectorHolder.getInjector().inject(this); in its constructor.
For example:
class MyPojo {
#SpringBean
MyDumbDAO dao;
MyPojo() {
InjectorHolder.getInjector().inject(this);
}
void justDoIt() {
dao.duh(); // dao is there!
}
}
Note that it will only work if called within a Wicket-managed request. If not (ie, if it's a Quartz job, or a Filter executed before Wicket's), the Application instance will not be available, and the injector won't know how to get the dependencies.
Another solution is to use Spring's #Configurable. It uses AspectJ to intercept creation of annotated objects, and inject its dependencies, even if you instantiate them directly with new (or some other framework, like Hibernate, creates them internally). But this requires runtime or build-time (works better for me) bytecode manipulation, which may be too much magic for some people.
#SpringBean only injects dependencies into classes that inherit from Wicket's Component. #Autowired only injects dependencies into classes created by Spring itself. That means you can't automatically inject a dependency into an object you create with new.
(Edit: you can also add a #SpringBean injection to your class by injecting in the constructor:
InjectorHolder.getInjector().inject(this);)
My normal workaround for this is to use my application class to help. (I'm a little puzzled by your use of new Application(...). I assume this isn't actually org.apache.wicket.Application.) For example:
public class MyApplication extends AuthenticatedWebApplication implements
ApplicationContextAware {
private ApplicationContext ctx;
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.ctx = applicationContext;
}
public static MyApplication get() {
return (MyApplication) WebApplication.get();
}
public static Object getSpringBean(String bean) {
return get().ctx.getBean(bean);
}
public static <T> T getSpringBean(Class<T> bean) {
return get().ctx.getBean(bean);
}
....
}
In my Spring application context:
<!-- Set up wicket application -->
<bean id="wicketApplication" class="uk.co.humboldt.Project.MyApplication"/>
My helper object then looks up the service on demand:
public class HelperObject {
private Service getService() {
return MyApplication.getSpringBean(Service.class);
}
The best practice would be to create your objects via a factory bean (that has those properties injected by Spring, and have that factory inject those properties to objects it spawns - pure IoC).
You should really avoid using SpringContext all over the place (or any other similar solution for that matter).
Here is a partial list of reasons:
Your code gets coupled with Spring way too much (low-cohesion).
You mix plumbing code with the business-logic.
Your code is less readable.
It's less maintainable (e.g., changing the name of the service bean would lead to code modification - this violates SRP & OCP).
It's less testable (e.g., you need the Spring framework to test it).