This is related to the question
How do i get servlet instance from web.xml in my java class
Folks were not clear as to what is the usecase for this type of question. I have the same question and wanted to give a usecase.
In my application i have a class called Configuration which extends HttpServlet. In my web.xml i have an load-on-startup servlet defined for Configuration. This class reads all the properties necessary for the application, and it is absolutely necessary that this properties are read during startup because there something which i am doing differently for each instance of my webserver based on the properties. Now i need to get a handle of this instance in my spring controllers so that i can get the values of the properties. How do i do it?
Is there any specific reason why Configuration is a Servlet? If this class's sole purpose is to read properties to be used later and it is not serving any requests by itself, it shouldn't be a Servlet.
There are two ways to do these configuration classes.
One, you can annotate this class as a #Component and make this class to be instantiated by Spring during startup. Then you can inject this bean wherever you need it.
Second way, without using Spring, is to register an ServletContextListener in your web.xml. Create a class implement the ServletContextListener and inside the contextInitialized() method, call the method of the Configuration class where your property loading logic resides.
http://www.mkyong.com/servlet/what-is-listener-servletcontextlistener-example/
Related
I've been playing around with the concept outlined in this answer, to share a common 'contract' between server and client. I'm trying to use this concept in a Spring MVC application that contains both REST endpoints and a Feign client. The #RequestMappings on the REST endpoints are picked up like normal by Spring, but: it also picks up the #RequestMapping on the abstract API class I use for my Feign client, i.e., in terms of the linked example, I have a UserService and UserClient in my code, and Spring picks up the #RequestMapping in the UserService class.
I don't understand why this happens in the first place, because:
The UserService class is an interface. Why and how does Spring think it can map an endpoint to an interface method?? This will obviously never work.
The package containing UserService is not included in the basePackage list of the #ComponentScan annotation on my Application class
Any clues on how I can convince Spring to just ignore all classes in this package??
So apparently this is a known issue, see this thread for ways to fix it.
I want to know whether I can use object of service layer marked with #Service annotation and call one of its method in non mvc-spring class ?
Say there is a method getUsers() in service layer which calls getUsers() of Dao layer. In order to use it in contoller I have to add the #Autowired-annotation in the service layer instance. But if I want to use the class method getUsers() in non-mvc class, how can I do that?
In order to use a service, that object must be container managed. That is, this object's life cycle must be managed by Spring (creation, destruction, initialisation,...).
So to inject an instance of your service in an object, it must be a Spring bean too (Service, Component, Controller...).
So, it may be an MVC object, but it doesn't have to.
On the other hand, there is another alternative: use the annotation #Configurable.
An object with this annotation can be application managed but Spring, using byte code aspects, can inject it's dependencies. So although you create the object with a new statement, Spring instruments this call and resolve all the annotated dependencies.
Read this for more detail:
http://docs.spring.io/spring/docs/3.0.0.M3/spring-framework-reference/html/ch08s08.html
Is it a good practice for a class to extend HttpServlet and implement ServletContextListener?
public Myclass extends HttpServlet implements ServletcontextListener {
}
What are the pros and cons of doing this?
Some thoughts:
You will have at least two instances of your class. The container create one as ServletContextListener and at least one as HttpServlet when your servlet get an incoming request.
Since the 2+ instances you cannot use instance (just static) members to share data.
It's easier if other classes don't use the data/objects that you initialize and share in the listener because you don't have to put these data/objects to the application scope in the ServletContextListener and retrieve them in the HttpServlet.
If your initialization logic is complex maybe it's worth to separate it from the servlet code (e.g. putting the initialization code to a different class and using the application scope to get the shared objects in the servlet).
It all depends on you, the implementer. ServletcontextListener has its particular purpose. Make sure you know what it is for before using it.
In case you are creating an HTTP servlet you must extend HttpServlet.If your class wants to "receive notifications about changes to the servlet context of the web application" (copied from javadocs) it is part of, you have to implement ServletcontextListener.
I'm new to using StructureMap as an IOC container for asp.MVC. One of my controllers takes an IStreamService interface in the constructor.
This is easily linked to a concrete class implementation of StreamService like so
For<IStreamService>().HttpContextScoped().Use<StreamService>();
The problem i'm facing is that the concrete class constuctor takes an IPrincipal parameter, which needs to be injected. I want to pass the User property of the instantiating Controller into the Concrete Service. Could someone please point me in the right direction?
No problem, just add this line to your configuration:
For<IPrincipal>().Use(() => HttpContext.Current.User);
The use of a lambda causes this to be evaluated every time the dependency is requested (as opposed to being a single instance at configuration time.
I want to call to a method from an EJB in the same instant in which one deploys itself, without using a servlet.
Thanks.
David.
There seems to be no life-cycle methods defined by the EJB spec for this purpose. Individual vendors may provide extensions to allow this. For example Startup Beans in WebSphere would be a place to put the invocation logic you want.
Using techniques such as a static method seem slightly dangerous in that we don't know whether all dependency injection is complete before that static method fires, and hence whether you can safely use the business methods of the EJB.
Persoanlly, if I needed to be portable I would bite the bullet and use a servlet. It costs very little.
Try doing your initialization within a static block. This will run once when the classloader loads the class.
static { System.out.println("static"); }
The PostConstruct hook is right for that.
Find more info on about PostConstruct here:
in the javadoc
lifecycle of EJBs in the JavaEE 5 tutorial
Let's finish with a quick example:
#Stateless
public class TestEJB implements MyEJBInterface{
#PostConstruct
public void doThatAfterInitialization() {
//put your code here to be executed after creation and initialization of your bean
}
}
Static initializer blocks are technically not illegal in EJB but they are used to execute code before any constructor (which might be a problem) when instantiating a class. They are typically used to initialize static fields which may be illegal in EJB if they are not read only. So, what about using ejbCreate(), setSessionContext() or setEntityContext() methods instead (not even sure this would be appropriate without more details on the problem you are trying to solve)?
The EJB container, for a #Singleton bean, shall create the instance of the bean as soon as the application is deploy if it is annotated #Startup.
That will, of course, fire up static initialization blocks, the constructor, dependency injection setters, #PostConstruct methods etc.
Here is the appropriate referente to the Java EE 6 Tutorial.