There are two WARs deployed in Tomcat (or other server), foo1.war and foo2.war.
All spring beans are defined in foo1.war, but is it possible to get these spring beans in the servlet that deployed in foo2.war?
I cannot just use WebApplicationContextUtils to get the WebApplicationContext, right? They are different WAR.
thanks
Technically, you can get the WebApplicationContext of the other app, if you expose the servlet context and call servletContext.getContext("/otherapp").getAttribute(..), but that's ugly.
You can have instances of the same bean definitions if you simply move the common definitions to a common.xml and include it in both projects.
If you need to communicate some data betweent the two apps, use another mechanism: web services (soap, rest), messaging (jmx).
Adding to #Bozho answer: you can also share instance data (e.g. singletons), when the two WARs are deployed in a single EAR. You should be able to expose the appContexts as statically visible fields in a class provided by EAR and thus visible to both WARs.
Related
I'm running a web-server (Embedded Jetty) that hosts multiple WARs and also supports hot deployment of new\exisitng webapps (as described here).
I have a set of common beans which needs to be shared (same instance) between the different web-apps. Is it possible to use Spring to somehow handle this beans?
Found this excellent explanation, but it explain how to do it with EAR files, which is not an option on my side since as I mentioned we support hot deployment of new WARs, we don't want to redeploy all the web-apps when deploying one web-app.
Is it possible to use Spring to handle these beans? or do I need to create some kind of wrapper in my common-beans to behave as a singleton (all web-apps runs on the same JVM)
The background & requirements are:
there are a lot of old projects which have an applicationContext.xml and one or more dispatcher[-XXX]-servlet.xml. We hope those projects can still works while using spring boot(we developed a deployment tools to deploy spring boot applications, but the old projects are still deployed manually). But, #SpringBootApplication can't build the contexts as they were. And rewriting them into codes one by one costs too much, I think.
In those project, we use an extended RequestMappingHandlerMapping, so we can't use the native MVC.
the context.xml of tomcat, which contains jndi definitions, is maintained by OPs. We have to load it just like tomcat does.
i can't find where to set welcome file, which were set in web.xml
I currently using:
#Configuration
#ImportResource({"classpath:/applicationContext.xml", "classpath:/dispatcher-servlet.xml"})
Those simple projects without using jndi can startup.
But as my understanding, in this case, the applicationContext and dispatcher-servlet are in the same level(dispatcher-servlet should the child of applicationContext, isn't it?). So, i can't even ensure this one works properly.
We did a similar thing about a year ago and your setup was more or less the same as ours and importing those XML files did the trick; the only thing we had to do was to ensure our application class was in a different package hierarchy in order to avoid conflicting/duplicate bean definitions due to its inherent #ComponentScan.
And having dispatcher servlet and application context in the same context won't cause any issues - yes, dispatcher servlet's context is usually defined as a separate context and is a child of the more broad applicationContext but what most people fail to grasp is that that separation only matters if your application wants to have more than one dispatcher servlet, which is rarely the case any more, if it ever was.
In case of multiple dispatcher servlets it was a must to enable them to have different WebMVC configurations, and applicationContext was there to allow you to share common beans and configuration between your servlet contexts so that you don't have to do the same work twice.
Imagine I have one Spring Boot instance, pretty boring, one ApplicationContext, starter-jetty. By default, it does one ServletContext on /, puts a DispatcherServlet on / too. Every servlet and filter then placed under this context.
Now, I want to have one servlet context with contextPath=/api with a few servlets and another servlet context under /internal with a different set of servlets. They have to share ApplicationContext and most beans. And yes, it has to be plain old servlets & filters, not just two WebMvc instances.
How do I configure that? The most crucial question is how to make two ServletContext's for Jetty to consume. Just class names are enough, links to examples are encouraged. Hints on how to painlessly configure the distribution of Servlet's and Filter's between servlet contexts are appreciated too.
I have an enum that I inject into the application scope such as
public void contextInitialized(ServletContextEvent sce) {
sce.getServletContext().setAttribute("app", ApplicationProperty.INSTANCE);
}
My question, is I have to deploy this web application twice with different property files. Would that cause a problem since I am using an enum, would they share the same values? Thanks.
Application is deployed twice with different context paths and property files (think of as secretKey=12923 and the other one has secretKey=48984 in the property file). First instance deploys it as /ForInternalUse and the other deployment /ForExternalUse. Both deployments are under the same web app server (glassfish).
PS. I have done a small test on glassfish 3.1 but it seems properties are not shared. Second deployment does not impact the first deployment.
The two deployments will not share the same enum - they are kept separate unless you specifically share objects between them.
The reason is that an enum is only unique to the classloader that loads it - it is not unique JVM-wide. Web servers provide each context with its own classloader.
See here for how if you wish to share.
In Spring MVC, there are two contexts. One is the application context or global context which is booted up by ContextLoaderListener. It takes all the configuration files mentioned in contextConfigLocation parameter.
Now if you are using Spring MVC as well, then Dispatcher servlet is required, which boots up another container which is also known as web application container. This container takes the global container as a parent.
When integrating struts1 with spring, there is only one context. Why does spring mvc need two? Is it possible to use only one context when using spring mvc?
thanks!
Having a root web application context plus a child servlet context is just an option. If you know that your application won't have a second servlet, it's arguably simpler to have one single Spring context for the whole web application.
You can achieve that setup by simply removing the ContextLoaderListener (and the accompanying contextConfigLocation context-param) from your web.xml and moving all bean definitions into the xml defining the servlet context ([servlet-name]-servlet.xml).
This is possible, because the FrameworkServlet (super-class of DispatcherServlet) doesn't care if there is a root application context when creating the servlet context. It just relays the root context as the parent if available. See related code here.
Imagine you had two separate Dispatchers, each serving a different purpose, and each having its own dependencies. You would configure those independently using separate contexts.
If there is any shared configuration, this can go in the 'global' context.
I don't think it's possible to have only one context using DispatcherServlet, as it creates its own context and links it to the parent context (via the FrameworkServlet superclass).
FrameworkServlet.createWebApplicationContext
Check this answer About multiple containers in spring framework
Yes ,you can have one context only.
For code reuse it would be better to isolate services in Application Context rather then WebApplicationContext.but this not compulsion.you can keep only webApplicationcontext only.