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
Related
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.
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.
Excuse me if this is has already been discussed, I could not find a satisfying answer.
I do not understand whats happening when i create a bean in Springframework and #Autowired it to a field in another bean. I understand the result of #Autowired and other annotations but i do not know how its done by Spring.
class Sample1{
//
}
class Sample2{
#Autowired
Sample1 sample1Bean;
}
<bean id="sample1Bean" class="...Sample1"/>
<bean id="sample2Bean" class="...Sample2"/>
My question is how does spring set the field sample1Bean in Sample2? i am not expecting a complete explanation, but a direction where i have to look would be great. Thanks.
The #Autowired, #Inject annotations are resolved by a BeanPostProcessor - specifically AutowiredAnnotationBeanPostProcessor. This bean post processor intercepts the creation(for cases where #Autowired is on constructors) of beans, setting of property on the beans to ensure that all the autowired fields are appropriately set.
Im no expert in Spring but I will answer what I know. When a spring powered web application starts up, Spring framework goes through bean instantiation process in the application context. While creating beans Spring checks the required dependencies for a given bean. It looks up a matching bean based on the required type of bean and autowires it when #Autowired annotation is specified.
In the above example, Spring will go through application context and create a bean(object) of type Sample1. When it will construct bean Sample2 it sees #Autowiredannotation and will look for instantiated bean of type Sample1. When it finds bean of type Sample1 it will inject that bean on Sample2 and finish creating Sample2. This is called dependency injection and is one of the very popular features of Spring framework.
Hope this helps.
Does a class which will act as a bean in a Spring application require both #Component and #Named at the same time?
What is the significance if both are used so?
I tried searching the net as well as saw the standard documentation of these annotations and found them a bit confusing.
Finally which name is taken by the application if the #Named annotation does not specify any name for the bean?
#Component and #Named are annotations that basically do the same thing, but come from different APIs.
#Component belongs to Spring API. It marks class to be autodetected as a bean and optionally allows you to specify a name for that bean (#Component("foo")). Without explicit name specification detected bean will get a default name derived from the name of its class.
#Named belongs to javax.inject API. It marks class to be autodetected as a bean and requires you to specify a name.
Spring supports both these APIs. It doesn't make sense to use both annotations at the same class since they provide the same functionality.
See also:
3.10 Classpath scanning and managed components
Spring supports #Named annotation (JSR-330) as an alternative to #Component (Spring).
Generally, #Named is poorly named since doesn't describe what it does, so I would prefer to use #Component whenever I can.
Either of the both should be used.
Using both #Component and #Named don't make any sense.
Adding to above (Other's) comment #Component("[someComponentID]") and #Named("[someNamedID]") to assign an ID to a bean by passing the ID in the parenthesis, if not implicitly assigned one.
I was reading Spring 3.0 documentation and I came to the sentence -
Annotation injection is performed before XML injection, thus the latter configuration
will override the former for properties wired through both approaches.
Next the question came to my mind:
If I use an annotation in a bean (like #Service("myService")), now I am using the other bean and it uses "myService", and "myService" would be injected through XML configuration.
Would this work? I tried but it is giving me
BeanCreationException (Cannot resolve reference to bean 'myService' while setting bean property 'myService')
Later, I went through this question Wiring Spring bean through annotations and xml context, but in the solution it is told that "Just leave all your annotated fields unspecified, and they'll get injected auto-magically." (I didn't try out this solution)
But what if I want to specify all annotated fields, like I specified #Service annotation above?
Any suggestions??
I figured out the answer, it works very well. Actually I forgot to add tag in xml configuration. We need to add this tag in each config file i.e. if you have written config file for service layer beans, add tag for service layer annotated beans. Similar for dao and controller layers.
You need to autowire your constructor like below...
#Autowired(required=true)
public UserService(DataSource dataSource){
this.userDS = new UserDS(dataSource);
}
So, in the above code the DataSource will be injected in the UserService automatically.