I have 2 spring contexts: "webapplication" context and a "core" context. The context "core" is initialized at server startup and attached to a Singleton class that holds the context. The "webapplication" context is initialized when the webapplication is started.
I want to inject bean dependencies from beans in one context to the other (bidirectional access). The webapplication beans are to be "session" scoped beans.
I'm testing this proof of concept with: webapp bean --> (that depends on) core bean --> (that depends on another) webapp bean.
At the webapplication context initialization i could inject "core" beans to the "webapplication" beans (a BeanFactory that acceses the singleton do the magic), but can't figure out how to do the inverse; because the Spring ThreadLocal that holds the WebApplicationContext is not yet initialized.
The question is. Is it what i'm trying to do possible? If the answer is "yes", how would you do that?
Thank's in advance.
EDIT:
I'd realized i'm doing something wrong. The fact is that i'm trying to inject in the service layer a dependency to a session bean, at the wrong time; that is, at the web initialization time when i have no current user session.
This looks to me like an architectural issue, not a technical (and certainly not Spring) one. Your separation between core context and web context is very good. The former handles business processes while the latter is responsible for representation, maybe some API.
The dependency from web (representation, access) to core is understandable and required - after all you are building an interface over business routines. This is how spring-mvc works by default, creating separate child (web) application context of core context.
I can hardly imagine a use case for inverted dependency. Why is your business logic depending on web layer? What if you try to migrate your application one that to a different representation technique (desktop, mobile)? Can you justify the reason for this inverted dependency? What do you mean by session bean?
Bidirectional dependencies, as well as static singletons holding a class-loader wide reference to application context should indicate that something is wrong with the design.
Related
Per the Spring Documentation, application context is:
Central interface to provide configuration for an application. This is read-only while the application is running, but maybe reloaded if the implementation supports this.
In some applications, there are multiple application contexts. What's the purpose and benefit of having multiple application contexts? I want to understand the logic behind it. Why would one do it?
P.S: In spring doc use is written. I want to know the pros of having multiple application contexts and the rationale behind it.
The root context is the parent of every dispatcher servlet context/child context. Beans defined in root context are visible to each dispatcher servlet context/child context but not vice-versa.
Typically, root context is used to define all cross-cutting beans such as security, transactions, and other configurational beans, while the dispatcher context or child context contains those beans that are specifically related to MVC.
We create multiple dispatcher servlets when we need multiple sets of MVC configuration. For e.g. we may have a REST API alongside a traditional MVC application or an unsecured and a secure section of a website.
Cannot comment so putting the answer:-
Java Spring multiple ApplicationContext
Hope this answer your question
It is useful to implement a layered architecture (model objects, data access, services, web services, mvc app etc).
As M.Deinum said it is good to have one root context that loads the others and helps keeping them separated.
Here is the official doc for the architecture of Spring Framework applications: https://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/overview.html
As far as I understand "pre-CDI" EJB and resources injection solutions (#EJB, #Resource and others, to be clear) use the JNDI service to locate objects "known" to the container by virtue of being JNDI registered, and then inject them where requested.
CDI, instead, relies on bean-discovery-mode parameter (ALL or ANNOTATED) to discover beans that need to be managed. But how is this process actually performed? A runtime scan of... what? Is JNDI not involved at all?
I have the feeling I'm getting something wrong about the whole mechanism...
The bean discovery process is described in detail in the CDI specification. Basically, the CDI container scans bean deployment archives for classes with certain annotations.
JNDI is not involved at all. Unlike EJBs, CDI beans cannot be looked up via JNDI in general.
Only the BeanManager itself can be looked up under the name of java:comp/BeanManager, but this is almost never required, unless you need to access managed beans from unmanaged code.
I am trying to understand how to best make use of spring application context hierarchies. Assuming I have an Application where I have #Controller beans, #Service beans, and #Repository beans, representing a front-end, business and persistence layer, it would seem nice if the layers had contexts in which only beans are visible which are relevant to the context. It would also be nice if I did not need special code for creating beans, just using #Autowired should be enough.
I can create a context for my repositories, let's say repoContext, in which there exist only the repository beans. The service layers needs access to those, but not vice versa, so I'd might create another context serviceContext which has repoContext as parent. Now the front-end layer needs the services, so I might create a controllerContext with serviceContext as parent. But doing so, the controllerContext would also be able to deliver repository beans to the front-end layer, which is the opposite of what I wanted.
So it seems to me that to properly separate bean dependencies in separate contexts, the parent-child relationship is not very useful to provide dependencies to a context.
Is there any better way? Could there be a front-end and a backend context sharing configuration of the service beans, but with the backend context being resposible to insatntiate service beans first (because only this context has repositories)? Or would that approach lead to the frontend context trying to instantiate own service beans?
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.
Coming from plain old DI of Spring I can't figure out how to choose scopes properly while writing with CDI.
In Spring all my services have singleton scope by default, which I suppose maps to application scope in CDI (or even #Singleton). I know for e.g. logged in user information I need to use Session scope and for e.g. form params I need request scope.
Say I have a bean that hides external service API calls. It is completely stateless. Should I put it as #Singleton or simply application scoped? Or let it be created on every request (possibly bad option).
Is this correct to inject everything everywhere? In Spring I create my data objects by new. Should I do the same in CDI or simply #Inject them?
Are you only using CDI? or a Java EE 6 container? If you have a stateless class that is used for service calls, then I would recommend using #Stateless, which is from the EJB spec (so you would need a Java EE 6 container) It isn't a singleton, but it doesn't get created on each request either. I believe it is more closely bound to the session, but since it is stateless, instances can be pooled and shared. If you are only dealing with CDI, I believe Singleton matches more directly to Spring's singleton, but I would recommend using ApplicationScoped because it provides a proxy which makes serialization of beans that use it easier.
#Service
#Scope("prototype")
public class CustomerService
{
......
}
Just add #Scope("prototype") annotation to your component.
Is there a reason you would need the bean to remember it's state? If you are using something like a web client, that is a better place to store state in say, session scoped managed beans (assuming jsf), or whatever equivalent for your case. On the back end server side your EJB's would be better kept as #stateless to keep overhead to a minimum and help with the 'keep it simple s..." paradigm. And in case this works, just declare #Stateless on your bean. Unless there is a reason to use a singleton, again it is better to use a stateless bean if you want to go with a Java EE container for your services.
Stateless beans are not really being recreated with every request. That is the purpose of the pool. The app server keeps a ready supply of stateless beans on hand, and if it gets busy, it will make more, and if it quiets down, it will empty some out.