I have a xml bean definition and JavaConfig bean definition in the same project. The JavaConfig need to reference the XML bean. But When i autowire the xml bean definition inside JavaConfig I get NoSuchBean definition error. My question is: Isnt the xml beans and JavaConfig beans visible to each other? If not how do i inject the xml bean into JavaConfig? Thanks
Edit:
Changing #Autowire to #Resource fixed it, but i dont understand why. Autowire should go after type and the XML bean is of the type Autowire is annoted with.
If your bean is not being picked up by Autowire, you need to ensure the configuration file for the beans is being read and in turn is generating the beans.
One easy way to check is if you are using an IDE with Bean detection capability to see if the IDE is picking up the bean.
If this is working then please paste in your code of the xml with bean in it and xml containg your scan ability.
Related
I am having two beans in different packages out of which one of them is a library so cannot edit, and execution gives the
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type '' available:
For current purpose I want the bean in the library to be the primary bean, is there a way to avoid using the second bean which i can edit , without deleting the bean?
So far have only seen the #Primary annotation
when spring is trying to inject the dependency it found to to beans for it .
so you have add #Qualifier annotation and give the corresponding class in it which you want to inject
How Spring able to read or implement the Annotations called #Autowired, #Component and where the logic available in spring source code?
Spring context understand annotation by set of classes which implements bean post processor interface. so to handle different type of annotation we need to add different annotation bean post processors.
if you add in you configuration xml then you need not to add any annotation bean post processors.
Post processor provide methods to do pre and post processing for each bean initialization. you can write your own bean post processors to do custom processing by created a bean which implements BeanPostProcessor interface.
Annotations are metadata that can be read from the java source code. Spring Container understands what has to be done when it encounters these annotations in a source file.
Read through on each of these annotations.
Component
Autowire
More on Autowiring
1.4.5. Autowiring Collaborators
The following class does the autowiring magic.
AutowiredAnnotationBeanPostProcessor
Lately I am confused about 1 thing.
I defined PlaceHolderConfigurer in applicationContext.xml and config 1 bean in applicationContext.xml too, for example it's called myService which has a property: name I inject value with #Value($env{name}).
And this bean is also annotated with #Service annotation, then I add <Component-scan.....> in dispatch-servlet.xml.
I thought the property: name doesn't get value, because Xml bean is overridden by component scan bean andPlaceHolderConfigurer can't be shared between application context and dispatch servlet context, but actually it have value which I configured in property file.
So is there anyone can explain a little bit for me?
Anything will be appreciated. Thanks
You created two versions of one bean - one defined in applicationContext and one in dispatcherServlet. That usually wrong.
As you suggest PlaceHolderConfigurer not shared beetween parent/child context. It works only for context where it defined.
In Springs latest version, we can autowire a bean using annotation as #Autowired. This will autowire the bean using its type(or constructor, if applied on it).
Is there any way I can use the #Autowired annotation based on the bean name which we were doing without annotation in Spring's XML file as autowire="byName"?
You can use:
#Autowired
#Qualifier("beanname")
According to the #Qualifier javadoc
This annotation may be used on a field or parameter as a qualifier for candidate beans when autowiring
You can use JSR-250 #Resource for by-name bean autowiring, unless you need constructor injection or multi-parameter method injection.
From the docs:
If you intend to express annotation-driven injection by name, do not primarily use #Autowired, even if is technically capable of referring to a bean name through #Qualifier values. Instead, use the JSR-250 #Resource annotation, which is semantically defined to identify a specific target component by its unique name, with the declared type being irrelevant for the matching process.
If you want to define name of the bean with which they will be registered in DI container, you can pass the name in annotation itself e.g. #Service (“employeeManager”).
Then using below code you can enable autowire by Name
#Autowired
#Qualifier("employeeManager")
private EmployeeManagerService employeeManagerService;
I was using bean name proxy which was messing up autowiring by name. #Resource didn't have that issue since it doesn't care about type. So now I know one reason for this recommendation by Spring developers :-) Just FYI
Use #Component("beanname") in the java class definition of your bean
Then while autowiring use JSR 330
#Inject
#Named(Value="beanname")
As far as I understand When Using Dependency Injection all bean are initializing on Start.
<bean id="userPreferences" class="com.foo.UserPreferences">
</bean>
<!-- a singleton-scoped bean injected to the above bean -->
<bean id="userService" class="com.foo.SimpleUserService">
<!-- a reference to the userPreferences bean -->
<property name="userPreferences" ref="userPreferences"/>
</bean>
and the configuration above means that userService and userPreferences created when application starts. Is it correct?
When using Autowiring and using <context:component-scan>
public class SimpleUserService{
#Autowired
UserPreferences userPreferences;
//omitted
}
1) Is userPreference created on Application init?
2) What is the default scope for bean injected by autowire and how can we change it?
3) How affects bean creation and bean injection?
Hope I made myself clear.
First of all you should add #Service or #Component to the SimpleUserService class.
1 Yes, the ONE instance of UserPreferences is created at application intialization
2 Default scope is singleton, You can change it with the #Scope annotation (#See Spring Reference: 3.11.4.4 Specifying bean scope)
3 Component scan and XML configuration work in the same way (life cycle)
Maybe you should spend some time in understanding the Spring life cycle. You need to understand that Spring works a bit in this way (not 100% correct):
first it creates a pool of beans
then it injects the properties into the beans
But it does NOT work this way: taking a class, look what references it needs creating this references (recursive) and then creating the class.
If you understand this, then you will also understand, that the #Scope of a bean is defined at the bean declaration/class, but not at the references.
1) Is userPreference created on
Application init?
In either case userPreferences is initialized when Spring Context is loaded. You can change this behavior by adding lazy-init="true" to the bean configuration.
2) What is the default scope for bean
injected by autowire and how can we
change it?
The scope of what is injected is all beans loaded into Spring. If you import an XML configuration from another project, it too would be included. I'm not sure if you can limit your scope.
3) How affects bean creation and bean
injection?
Whether is autowired, or configured via XML, the behavior should be the same. I prefer explicitly defining dependencies over automatic annotations. Then again I also like strongly typed languages.
the configuration above means that userService and userPreferences created when application starts. Is it correct?
Yes
Is userPreference created on Application init?
Yes
What is the default scope for bean injected by autowire and how can we change it?
The default scope is always "singleton". This can be changed either using #Scope with #Bean or the scope XML attribute on <bean>.
How affects bean creation and bean injection?
This isn't a clear question. If you change the bean scope, you change when it gets created (start of application, on each request, on each session, etc). The wiring configuration remains the same, only the lifecycle changes.
The #autowired notation is an obsolete way to say #inject. THe latter is a feature of JavaEE 6.
stackoverflow.com/questions/7142622/what-is-the-difference-between-inject-and-autowired-in-spring-framework-which