I am using a custom UserDetailsService to authenticate users. This uses a PersonDao/Service object that is autowired. To autowire this object, I had to include reference to datasource, sessionfactory and annotation driven in Spring-security-context.xml. All these lines are exactly replicated in app-servlet.xml. So I was wondering if there is anyway to have theses lines in only one place and not to copy it at both the places.
Your app-servlet (Spring MVC) context is a child of the root WebApplicationContext and has access to all of the beans in the parent.
If your parent context includes spring-security-context (for example)
<import resource="spring-security-context.xml"/>
then app-servlet will have access to those beans.
See What's a smart way to organize classes in Spring 3 for component-scan? for info on how to not duplicate beans when <component-scan>ing.
Related
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.
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 have read different articles on using #Stateful and #SessionScoped annonations and their differences including this post. From a definition point, #sessionScoped is used when a session is needed/created between client/web tier, while #Stateful is needed in Bussiness Logic layer. But I still do not get a hold of the real differences when it comes to implementing them. Here is a simple example
#Named
#SessionScoped
ShoppingCartUIBean {
#inject
shoppingCart cart;
// more code
}
#Stateful
ShoppingCart {
//business logic of adding/updating/deleting cart items
}
How is the Http session maintained by #SessionScoped bean between a given user and server?
That is, if I have a shopping cart opened in different computers, I should be able to see my shopping cart, which is associated with my user profile. How is this established?
what happens if I switch the two annonations on the above beans? will it have any effect?
(sorry this might sound stupid. I am getting into Java EE world, so I want to get basics correct).
According to this great post on Differences : #SessionScoped vs #Stateful and #ApplicationScoped vs #Singleton, #Stateful beans are hardly used in web applications. Is there a case where #Stateful is absolutely necessary?
ON a related note: is it legal to inject a #stateful bean into #ApplicatonScoped bean? This would mean entire the application has a single #stateful bean and all clients uses the same instance of one stateful bean via proxy. (Just as is demonstrated here, not to inject #Stateful in servlets EJB example for stateless and stateful beans difference).
Thanks.
I will try to answer some of your question with my best.
Ad.1 #SessionScoped is about browser session, so you won't see the same session on different computers(or browsers).
Ad.2 You can't think about those two as the same components only because the same scope. Fundamental think is that EJB and JSF beans rely on different architecture layers. EJB beans should implement business logic while jsf beans should maintain forms and other ui components.
Ad.3 #Stateful beans are very useful in seam framework. Using those beans and extended persistance context is solution for lazy initialization error(probably that's a reason why seam creators use those beans). I prefer Stateless beans according to performance but it hardly depends on use case(whether you want keep state or not).
Ad.4 In general you shouldn't inject "less scope" beans to "more scope" beans. Application scope will exist while session may be destroyed and what this application bean should have in place of destroyed session bean?
Correct me if i'am wrong with any of this answers.
I'm struggling to find some idea, tutorial or sample how to put some of the configuration of the webapp into database. There will be static configuration put in properties files like database connection, but there is some configuration which can be changed like email account, facebook account and best location for this in the database. That configuration should be loaded as soon as possible when webapp starts. Ideally all the configuration should be in some bean named Configuration.
Thanks in advance.
When a Spring webapp starts, Spring instantiates and injects all its beans. Once the beans are instantiated and injected, if a bean has a method annotated with #PostConstruct, it calls this method.
So you just have to define such a method, read the config from the database and store it in the bean (if you want it to be cached).
Inject this bean everywhere you need access to the configuration properties.
i integrate a flex app in a jsf-icefaces app (in a jspx site with the ice:outputmedia-tag) and want to access the same instance of a bean from flex by remote, that jsf inject.
i already connect with blazeds to a java-bean. this bean - like all other beans - get other beans by injection of jsf, but when i access the bean by remote from flex it doesnt hold the injected beans (like localizer and accesmanager, both session scoped) and i can't connect to the jsf session (FacesContext.getCurrentInstance() is null). this is because flex create a new instance of the bean and it’s not the same current instance, that jsf inject, i think.
i can connect from flex to the database by create a new entity manager in the java bean, but that's not what i want, because it's again another entity manager...i want persist and get data over the accessmanager-bean.
i know exadel fiji and flamingo, but i couldn't work with fiji, because my jsf app include the icefaces components and then it doesn't work with richfaces which fiji needs. and flamingo work only with jboss seam and spring. is it right?
i also read about the spring-flex-integration, but the jsf application did not create with spring and i don't want to integrate spring in such a large jsf app.
yesterday i read about the FlexFactory interface. this interface i have to implement in my own Factory and set it in the service-config.xml of blazeds as a factory read this. i still implement my own factory but i only get application scoped beans over the servlet context which i get over FlexContext.getServletContext().getAttribute("Bean"); and not session scoped beans...
i hope there is a chance to connect throw flex and jsf...
thanks!
FacesContext.getCurrentInstance() is null
This will only happen when the current request is not been passed through the FacesServlet. In other words, the request URL did not match the url-pattern of the FacesServlet. It's namely the one responsible for creating the threadlocal FacesContext instance.
But you actually don't need the FacesContext here. As JSF just runs on the top of the Servlet API, you can also go low level and make use of it to grab the session scoped managed bean. JSF stores session scoped managed beans as attribues of the HttpSession with the managed bean name as key.
Thus, if you for example have a session scoped managed bean with the managed bean name myBean and you have the HttpServletRequest at your hands, then you can also access it as follows:
MyBean myBean = (MyBean) request.getSession().getAttribute("myBean");