I'm trying to write a servlet 3.0 web app, just to learn basic servlet handling. Normally i would use spring.
Now I have a servlet which access a DAO which queries the database. Now, what is the best way to instantiate that DAO and use it? My best guess would be to have a private property in the servlet and create an instance of the DAO when the servlet is created.
But, will the servlet be created multiple times?
Is there something similar to springs dependency injection available in servlet 3.0?
EJB 3 dependency injection is extremely simple to use. A single annotation, #EJB, causes the injection of a declared bean. The injection of the SomeDAO bean into a Servlet 3.0 looks like this:
#WebServlet(name="Messenger", urlPatterns={"/Messenger"})
public class Messenger extends HttpServlet {
#EJB
SomeDAO someDAO;
}
The injected SomeDAO bean could be an interface or a no-interface view bean. As long as there is only one implementation of the interface, it will be injected without any ceremony.
javax.servlet API is one of the technologies included in java-ee.
CDI, is the Context and Dependency Injection technology in java-ee
So to answer your question, your use case could be solved by using only CDI and Servlets.
But most of the application servers that supports above (e.g. TomEE, Glassfish webprofiles), will also support EJB (which uses cdi) and JPA. EJB+JPA can be used to implement DAOs.
Arjan Tijms has put together a nice link overview of what is included and happening in the java-ee-7 world
Related
I am learning javaEE and I read somewhere about the main usage of cdi's was back then first in jsf-managed beans with annotations like #requestscope, #applicationscope, etc.. now in newer javaEE versions the cdi got available everywhere (even in ejb beans) so the question is, how do I have to annotate a class which shall be injected inside my local stateless ejb? I am asking this because the annotations like #RequestScope and all those are from jsf but I am not using jsf. Is #Default enough since its marked as default anyway? Is #Dependent better choice?
#Stateless
public class FooEjb{
#Inject Bar b;
}
// what annotation to put here?
public class Bar {
...
}
Yes you don't need JSF to use CDI in JavaEE.
If you are using CDI without using JSF, use the scope annotations from the javax.enterprise.context package.
#Default is a qualifier which as the name suggests the default qualifier. If you have multiple implementations/instances of the same class in your container, then you can use qualifiers to distinguish.
#Dependent is a scope which is the default scope. This means it will depend on the scope of the class it's injected in. A new instance of a #Dependent class will be injected every time a new instance of the class in which it is injected is created.
To enable CDI you need to put a beans.xml file in WEB-INF directory of your web project or META-INF directory of your EAR or EJB project.
According to the java ee documentation, no annotation is required in your case. A simple POJO is an injectable bean and receive the #Default annotation. No need to use JSF.
so I have a RequestScoped bean that I am trying to inject UriInfo into using the Context annotation. The application is a JAX-RS based RESTful Web Service running on Wildfly 8 (and subsequently rest-easy). If I inject the UriInfo into the resource itself, it will inject correctly. If I try to inject it into any of the injected children, it will not inject and ends up null.
This was working for me on Web Sphere 8.5...but now it doesn't work on Wildfly 8. Any ideas? The source code is at https://github.com/rpg-maker-repo/rmmv-api. The resource is "com.trinary.rpgmaker.resource.PluginResource" and the place where I'm injecting the UriInfo is "com.trinary.rpgmaker.service.LinkGenerator". Currently I have the injection of UriInfo removed and the code that implemented it commented out. I have tried many ways of trying to inject it and none of them work.
Yes, the jaxrs-cdi integration is not fully specified and the implementations are free to enhance it to the extent that they want. Jersey (e.g. glassfish) has a very powerful integration and you can inject jaxrs' #Context into cdi beans (see http://hnusfialovej.cz/2015/02/25/jersey-further-improves-cdi-integration/). Resteasy's (e.g. Wildfly) integration isn't so straightforward but you can achieve injection of UriInfo into cdi beans via jaxrs providers (see http://blog.christianbauer.name/Accessing%20request%20details%20with%20JAX-RS%20and%20CDI/) (tested on wfly 10).
So you have a JAX-RS resource A which injects a CDI bean B and you want to use #Context to inject UriInfo into B?
Is there any reference in the Java EE spec to indicate that this is supposed to work?
I don't think so.
#Context is specific to JAX-RS and is not mentioned in the CDI 1.2 spec. It is not supported by CDI (unlike #PersistenceContext, #Resource and other legacy injections).
You could try to use a Provider which accesses the #Context:
#javax.ws.rs.ext.Provider
public class ContextInformationProducer {
#Produces
#RequestScoped
public ContextInformation create() {
ContextInformation contextInformation = new ContextInformation();
contextInformation.setBrowserUserAgent(httpHeaders.getHeaderString("User-Agent"));
}
Altough I am not sure if this is good practise, for which I have the following question:
Using #Context in JAX-RS Provider to provide context information to CDI beans
I am experimenting with Java Dependency Injection. Many questions here on SO talk about jndi resources being wired. But I think, a java class can be wired using #Resource annotation. I have a simple servlet in which I have two properties to be wired using CDI. I am using Tomcat6, Servlet 2.5, and Weld configuration.
The servlet code:
#Inject
private HikariConnectionProperties hikariConnectionProperties;
#Resource(name = "connectionProvider")
private IConnectionProvider connectionProvider;
However I get the code compiled, deployed. But, when there is a request for the corresponding servlet I get javax.naming.NameNotFoundException: Name connectionProvider is not bound in this Context.
But, I have #Named annotation for the ConnectionProvider class. The same configuration works with #Inject for both the fields.
So, my first question is how can I fix this issue? And is there any way that I can specify scope for a particular injection(using only annotations of JSR) without using Spring's #Scope? Any example is a great help as I am a newbie to CDI.
#Resource only works in Tomcat when you set up a resource in your container. Here's a reference for your own sake: http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html
It expects that you're binding a JNDI entry called "connectionProvider" in Tomcat. CDI does not bind elements to JNDI, it has its own internal mapping of objects to scopes. #Inject works here as you likely have not setup a resource for this class in your resource configuration.
How to inject an object to a servlet?
I mean, that I cannot use a constructor DI because servlets are instantiated by a servlets container. And I also don't see a nice way of implementing setter-based DI for a servlet.
Should I use servlet listener? Are there any best-practices?
P.S. I don't have neither Spring nor Guice nor any other DI framework, I'm interested in manual dependency injection.
This is possible under Servlet 3.0. You register a ServletContextListener which programmatically registers Servlet instances with the addServlet(String, Servlet) method of ServletContext just before the app starts. Since you're instantiating the Servlet instances yourself, you can give them proper constructors and inject dependencies.
I created an example a while ago that illustrates the basic technique.
You can consume services which are created/managed by some IOC container (Spring, Guice)
You could create a ContextAware implementation and Pull out the beans as and when needed from Servlet
You could use JNDI, the Java Naming and Directory Interface, and #Resource to inject it.
Since Servlet 3.0 it is possible to register Servlet instances programmatically with javax.servlet.ServletContext#addServlet. This class has also a createServlet method which analyses some annotations and performs dependency injection. I wonder if I need this method if I don't need the annotation processing. I'd like to have a servlet with a usual constructor to set required dependencies via dependency injection.
#Inject
public MyServlet(SomeDependency sd) { // Constructor
...
}
Questions:
Is it possible to construct a servlet instance "by hand" without createServlet? (new MyServlet())
Is it possible to use the dependency injection mechanism of a Java EE server to perform constructor injection? How to do it? Or is a separate DI framework like Guice required?
The recent Java EE 6 standard now supports dependency injection for servlets, the relevant part is called JSR-299 or CDI. The JSR-299 reference implementation, JBoss weld, can be deployed into servlet containers like Tomcat or Jetty as well if you don't want to use a full Java EE 6 application server like glassfish v3 e.g.
By the way, with an embedded Jetty server you can use its custom API to add preconfigured servlet instances.
Guice does this out of the box without the need for Java EE servers.
http://code.google.com/p/google-guice/wiki/ServletModule