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.
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 am new to spring and not able to understand when to instantiate the class with new operator and when by using spring container.
example i found a code
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
EmployeeDao dao=(EmployeeDao)ctx.getBean("edao");
int status=dao.saveEmployee(new Employee(102,"Amit",35000));
System.out.println(status);
int status=dao.updateEmployee(new Employee(102,"Sonoo",15000));
System.out.println(status);
Employee e=new Employee();
e.setId(102);
int status=dao.deleteEmployee(e);
System.out.println(status);
}
}
i am using jdbc template. i have a doubt why we have new to instatiate employee class instead we should have used (Employee)ctx.getBean("employee"). using new operator would create dependency?
Pls help
From ProSpring book,
"Of the applications that we have built using Spring,
the only objects that are consistently not managed by Spring are domain objects. (Even though in Spring
it’s possible to have Spring manage domain objects by applying the #Component annotation to the classes
and assigning them with prototype scope, most of the time we will choose to manage domain objects
within the application.) The reason for this is that, practically, Spring does not need to be involved with
domain objects. Generally, you create many instances of your domain objects using the new() operator
and perform processing either in the service or data access layer. Although Spring also supports the
injection of new instance of domain objects every time it was requested (by using the bean scope
prototype), generally developers will not adopt this approach since typically domain objects do not take
advantage of Dependency Injection, because they generally have few dependencies outside of the DOM
itself, and they don’t require much configuration."
So, yes you could create beans of type Employee but then they wil have to be defined as prototype as be default all beans in spring are singletons. because there can be many employees and their objects, you obviously cannot have Employee as a singleton. but your concentration as to the utilization of spring features should be much more than managing domain objects.
The Spring IOC container is at the core of the Spring Framework. The container will create the objects, wire them together, configure them, and manage their complete lifecycle from creation till destruction.The IoC container gets informations/metadata either from XML or by Java annotations, or by Java code.
Yeah you can create Employee bean in your spring context xml file and make sure scope is prototype as
<bean id="employee" class="com.mycompany.Employee" scope="prototype"/>
so that on every request of Employee bean, you will get a new object Employee.
There are other scopes of beans
singleton : This scopes the bean definition to a single instance per Spring IoC container (default).
request : On every HTTP request a new bean will created and delivered.
prototype : on every request(api request) a new bean will be created.
session : This scope a bean definition to an HTTP session.
Note : It is not recomemded to create beans for database model class.because your persistent layer will take care of 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
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/
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.