Application scoped bean in Spring - java

I am learning about bean scopes in Spring and going through this link it says the bean behaves as a singleton across multiple servlet-based applications running in the same ServletContext. I am confused about what does servlet context refer to. Does it refer to the container like tomcat because they refer to multiple servlet based applications. As i understand it, it means if i have multiple web apps deployed on a single tomcat instance and i want these apps to refer/share an object then i create an application scoped bean?
Please help if my understanding is correct.

5 Scopes of Spring Bean:
1.Singleton
2.Prototype
These scope will only work for a web application
3.Request
4.Session
5.Application
How to define scope in .xml configuration file:
Singleton bean:
By default ApplicationContext has a singleton scope.This means only one object will be c
created. And if we call 'n' number of getBean() then all the bean will point to the same
bean. Constructor will only be called once.
Prototype:
Will create a new bean each time getBean() is called.
Each bean will have its own hashcode.
#ApplicationScope:
Scopes a single bean definition to the lifecycle of a ServletContext.
Only valid in the context of a web-aware Spring ApplicationContext.
Bean Initialization:
When does a 'prototype' scoped bean and a singleton scoped bean gets initialized?
Singleton scoped beans initialize when the container starts.
Prototype scoped beans initialize when we ask for it using the getBean() method.
Prototype bean also gets intialize when it is used as a dependency inside a singleton
scoped bean.

Related

Can you use scoped proxies with Spring Boot 2 #ConfigurationProperties?

Using Spring Boot 1.5.12, we create scoped proxies for #ConfigurationProperties beans. We do this so that we can effectively have property values that are scoped to the user/session/etc. We use a BeanFactoryPostProcessor to register a scoped proxy created by ScopedProxyUtils.createScopedProxy and change the scope of the target bean definition to our custom scope.
This worked great in Spring Boot 1.5.12. However, in Spring Boot 2, the introduction of the Binder API has made this stop working. This is because when Spring Boot binds #ConfigurationProperties in its ConfigurationPropertiesBindingPostProcessor, it uses Bindable.of(type).withExistingValue(bean) passing in a type (e.g. org.example.Foo) and the bean which is an instance of ScopedProxyFactoryBean. Bindable checks that bean is an instance of type which it's not and things blow up.
Does anyone know of a general way to accomplish this? Specifically, to replace the #ConfigurationProperties bean definition with a proxy while still allowing the properties to bind to the instance? I've considered delaying the creation of the proxy until after the target has already been bound by ConfigurationPropertiesBindingPostProcessor (i.e. in my own BeanPostProcessor). However, at this point the bean is instantiated and my proxy can only replace the bean. It can't really leave the original bean in the context as a target. So I'm struggling with how to do this using a BeanPostProcessor.
EDIT: I've created a simple example project that demonstrates the issue (with the ability to check out code that works on Spring Boot 1 and fails on Spring Boot 2).

How to create a bean in spring that is available to all users in my app?

I'm building an online chat application in spring just like the one on Facebook. I want to create a bean with a property[Array] called active-users. Then performs the following:
Whenever a user logs in, I'll add his/her userId into the array.
When an other user logs in, I'll display the users that are
currently online.
How do I create a bean which is available at all times?
For Ex : In servlets, this can be achieved by using the Servlet context :
ServletContext context = request.getServletContext();
context.setAttribute("userId", "123");
All beans in Spring are singletons by default, they will be alive during the whole application's lifecycle unless you'll do something with the spring context.
So just create a spring bean and declare a global list in it. You can access it anywhere where the spring bean will be injected from the current context.
It's simpler with Spring than in a pure servlet application, because all beans declared in root application context reside in fact automatically in the ServletContext and as such are unique in the application. And Spring can natively inject them in any controller or service bean to allow you to use them at will.
The only limit, is that they are unique per instance, so it won't be enough it you had a farm of servers for your application.

How do CDI beans behave when accessed by a JAX-WS web service?

I want to expose some functionality of my existing JEE7 web app using a SOAP based #WebService. Can/should this service inject my app's CDI beans? How do #RequestScoped, #SessionScoped, and #ApplicationScoped CDI beans behave, given that there's no HttpServletRequest to identify the current session or request? ie. How do they get looked up?
My observations:
#ApplicationScoped seems to work as expected
#SessionScoped seems to behave like request scope in that a new bean is created each time the web service is called, but it is subsequently accessible from other beans up until the service completes
#RequestScoped beans don't seem to be looked up property - eg. if my webservice injects two #RequestScoped beans, then one of those injects the other one, a new instance is created, rather than the first one being injected
My idea was to use the #Dependent annotation to make my session beans behave like request beans when injected into my #WebService, but this isn't working due to the request scoped behaviour noted above. I could just use my #SessionSoped beans as they are, but I'm concerned about the memory overhead since a new bean would be created for every web service request, and then persist for some 30 minutes or so, rather than being destroyed once the service has completed.
Any clarification or ideas would be appreciated!

Accessing beans in portlet specific context programmatically

I have a portlet application. It is configured using Spring framework IoC container. I am using org.springframework.web.context.ContextLoaderListener to load my context.
I have an application context at root level (applicationContext.xml) and a portlet specific context (MyPortlet-portlet.xml).
I have a portlet of type org.springframework.web.portlet.DispatcherPortlet which is wired up to a Controller. In the Controller I want to access one of the beans (e.g. bean with id "myBean") I have defined in my portlet specific context. I have tried
MyBean mybean = (MyBean)PortletApplicationContextUtils.getWebApplicationContext(
getPortletContext()).getBean("myBean")
However only the beans in my application context are available here - none of my beans in my portlet specific context are available.
Is there a way to access the beans in my portlet specific context?
Thanks
Firstly, can't you just wire in the bean to your controller in the normal way, rather than retrieving it programmatically?
Failing that, you should realise that getWebApplicationContext() gets a reference to the root webapp context, not the servlet app context:
Find the root WebApplicationContext
for this portlet application, which is
typically loaded via
ContextLoaderListener or
ContextLoaderServlet.
If your controller needs a handle on its own context, then it should implement ApplicationContextAware or BeanFactoryAware, or it can use #Autowired ApplicationContext if you want to use autowiring.

Spring ApplicationContext Bean Scope

When you create a Service bean or Dao bean in your Spring applicationContext.xml file, what is the scope of those beans?
Will every person who accesses the web application use the same instance of the bean, or is the bean instantiated for each user's session?
By default a bean created in Spring is of scope singleton, so yes each person will access the same instance in those cases. The alternative is to specify the scope as prototype.
More info on this here, sections 3.4.1 and 3.4.2:
http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-factory-scopes-prototype
By default a bean created in Spring is of scope singleton. However, if you use Spring DispatcherServlet and DispatcherPortlet, a bean scope is requested.

Categories

Resources