In spring the classes annotated with #Controller, #Service, #Repository, #Component act as Spring beans and will be instantiated by Spring container in singleton (Default scope).
Here the model beans are not annotated with any stereo type annotations.
My question here is whether the model beans are singleton or not i.e., if they come under Spring container.
If it is true then, how has the concurrency issue been handled?
Model attributes, ex. from #ModelAttribute annotated parameters, are not beans. They are not managed by the BeanFactory / ApplicationContext. They are created by the DispatcherServlet's MVC stack and provided to you. There's no concurrency issue (unless you create one) because a Servlet container handles each request in a single thread.
Related
I have been trying to understand spring beans. As per my understanding, by default all beans are singleton and a singleton bean with lazy-init property set to true is created when it is first requested and singleton bean with lazy-init property set to false is created when the application context is created.
So, in an application, when a user request comes in ( where each request is a separate thread), do all these threads share the same singleton beans when requested within the program/class?
Yes, if the bean is created with default scope, the bean is shared across threads. However, another scope can be used to achieve the behaviour you mentioned.
See: https://docs.spring.io/spring-framework/docs/3.0.0.M3/reference/html/ch04s04.html?
Yes, by default (scope == 'singleton'), all threads will share the same singleton bean. There are two other bean scopes, session and request, that may be what you're looking for. The request scope creates a bean instance for a single HTTP request while session scope maintains a unique bean for each HTTP Session.
For a list and description of all of the Spring bean scopes, check out: Spring bean scopes
The best way to understand this is to understand how #Autowired annotation works.
Or in other words to understand "Spring Dependency Injection".
You said, "
by default all beans are singleton
We use #Autowired when injecting one layer into another between two layers.
If exemplify: Suppose, I want to inject UserService UserController. UserService is a Singleton bean. Creates an instance from UserService and Stores its cache. When we want to inject this service with #Autowired annotation. This annotation brings the UserService stored in the cache.
In this way, Even if we do this inject operation in many classes.#Autowired inject an instance of UserService with singleton bean instead of dealing with one UserService at each time. It saves us a big burden.
This is the fundamental working logic of Spring Singleton Bean.
Also, Spring Ioc Container manages this whole process.
I read that Spring annotations like #Autowired, #Transactional & #PostConstruct are a form of / use BeanPostProcessors. So from what I understand about BeanPostProcessors, they are used to manage the lifecycle of a Spring Bean. Meaning you can specify any code which should be run before or after the intialization of a bean.
Now annotations like #Component or #Bean specify to Spring that it should create beans of this type. For example,
#Component
public Class Foo {
}
will tell spring to create a Bean of type "Foo" and then Spring will manage it's lifecycle. So does that make #Component and #Bean BeanPostProcessors?
I read that Spring annotations like #Autowired, #Transactional & #PostConstruct are a form of / use BeanPostProcessors.
Neither, it's actually the opposite. It is BeanPostProcessors that look for the annotations and react accordingly.
AutowiredAnnotationBeanPostProcessor - BeanPostProcessor implementation that autowires annotated fields, setter methods, and arbitrary config methods. Such members to be injected are detected through annotations: by default, Spring's #Autowired and #Value annotations.
Also supports JSR-330's #Inject annotation, if available, as a direct alternative to Spring's own #Autowired.
CommonAnnotationBeanPostProcessor - BeanPostProcessor implementation that supports common Java annotations out of the box, in particular the JSR-250 annotations in the javax.annotation package. These common Java annotations are supported in many Java EE 5 technologies (e.g. JSF 1.2), as well as in Java 6's JAX-WS.
This post-processor includes support for the PostConstruct and PreDestroy annotations - as init annotation and destroy annotation, respectively - through inheriting from InitDestroyAnnotationBeanPostProcessor with pre-configured annotation types.
Note that #Transactional is not handled by a BeanPostProcessor.
Now annotations like #Component or #Bean specify to Spring that it should create beans of this type. [...] So does that make #Component and #Bean BeanPostProcessors?
No.
#Component is an annotation that the component-scanning framework looks for to find beans to register. The component-scanning framework also looks for annotations that are themselves annotated with #Component, such as the #Configuration, #Controller, #Service, and #Repositiory annotations.
The #Bean annotation is then handled by a BeanDefinitionRegistryPostProcessor (not a BeanPostProcessor).
ConfigurationClassPostProcessor - BeanFactoryPostProcessor used for bootstrapping processing of #Configuration classes.
This post processor is priority-ordered as it is important that any Bean methods declared in #Configuration classes have their corresponding bean definitions registered before any other BeanFactoryPostProcessor executes.
No! They are different.
BeanPostProcessor is used to perform some operations before and after creating a bean,this allows us to add some code before and after creating the bean.
BeanPostProcessor class has two methods.
postProcessBeforeInitialization : It's used to make sure required actions are taken before initialization. e.g. you want to load certain property file/read data from the remote source/service.
postProcessAfterInitialization : It takes care of tasks that you want to do after initialization before bean reference is given to application.
Refer to : spring-doc-beans-customizing-using-BeanPostProcessor
interface for details.
#Component : It's the most generic Spring annotation.
A Java class decorated with #Component is found during classpath scanning and registered in the context as a Spring bean.
Refer to : spring-doc-component-annotation for details.
I have a bean with #RequestScope in it, and when I inject it in one of my Singletons, it is injected as a singleton and not as a request scope. However, if I change the #RequestScope to #Scope( value = "request", scopeName = "request", proxyMode = ScopedProxyMode.TARGET_CLASS), Spring creates the bean as request scope and injects them to the singleton correctly.
I read the documentation of Spring regarding this:
The JSR-330 default scope is like Spring’s prototype. However, in order to keep it consistent with Spring’s general defaults, a JSR-330 bean declared in the Spring container is a singleton by default. In order to use a scope other than singleton, you should use Spring’s #Scope annotation. javax.inject also provides a #Scope annotation. Nevertheless, this one is only intended to be used for creating your own annotations.
Does this mean also that #RequestScoped is really being ignored by Spring? Is there any Provider/Resolver that resolves this issue with Spring? As much as possible I want to use the #RequestScoped annotation instead of #Scope annotation of spring as we are required to use JSR annotations only
http://docs.spring.io/spring/docs/4.2.5.RELEASE/spring-framework-reference/html/beans.html#beans-standard-annotations-limitations
As mentioned by by M. Deinum, Spring doesn't support #RequestScoped out of the box. I had to create a ScopeMetadataResolver to convert #RequestScoped into Spring #Scope
I referred here for my custom resolver:
https://github.com/matzew/spring-cdi-bridge/blob/master/src/main/java/net/wessendorf/spring/scopes/CdiScopeMetadataResolver.java
In an imported spring context XML file I define a bean instance that implements BeanPostProcessor.
In the importing spring context I define a number of beans (using BeanDefinitionBuilder in a custom BeanDefinitionParser).
Not all defined beans are given to the postProcessBeforeInitialization() method on my BeanPostProcessor.
It seems that some other FactoryBeans somehow affect this situation. When looking in the ApplicationContext instance with a debugger I can see all my beans inside - also the ones not being given to the BeanPostProcessor.
How can this happen?
With the concept of CDI in EJB3.X, you can inject the beans or entities.
What i want to know is: which types of beans you can inject.
Session Bean in Entity? Entity in MDB, etc???
How can I find a table that show the possiblities what i can do/inject in CDI concept.
Take a look at DZone Ref Card can be found here.
Quick Look:
Session Beans can be injected into Session Beans, MDBs can be injected in SessionBean, Entities can be injected in SessionBean.
Stateful beans shouldn't be injected in stateless beans.