I have a property file converterValues.properties having these data valueOne=1,valueTwo=2
i am trying to use the annotation
#Value("#{converterValues.valueOne}")
private transient String dataValue;
I want to load all the properties at once not each at a time using converterValues.valueOne
let me know how to get valueOne=1,valueTwo=2 at once using annotation.
I want to avoid defining #value for each key.
First create a qualifier annotation, let's call it #ConverterValues.
Then declare a bean of type PropertiesFactoryBean with the given qualifier.
<bean id="converterValues" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:path/to/properties" />
<qualifier value="your.package.ConverterValues" />
</bean>
Now you can inject the properties into your bean:
#Autowired
#ConverterValues
private Properties converterValues;
Update
You could, of course, skip the overhead of defining a qualifier if you are willing to express the dependency explicitly:
#Autowired
#Qualifier("converterValues") // the name of the bean to inject
private Properties converterValues;
Related
My understanding about the #Autowired annotation applying on a property of a bean is that by doing that we can eliminate the setter method. This seems valid when we choose to annotation based configuration: we just create a bean annotated with #Component and annotate #Autowired to its property of interest.
However I failed to do the same when I tested the idea using xml based configuration.
Here is what I put in the bean class:
#Autowired
private String message2;
public String getMessage2() {
return message2;
}
In the xml file:
<bean id="testBean" class="TestBean">
<property name="message2" value="Hello world!"/>
</bean>
the IDE complained "can't resolve the property" and failed to compile. Maybe using #Autowired with xml configuration is an odd marriage that is disallowed?
Anyone care to help me on this might-be-silly question?
If you don't want the setter, then get rid of the <property> element in your TestBean bean definition. That property requires that a setter be available to set the property. Because it's missing, if you actually tried to load the XML configuration, with a ClassPathXmlApplicationContext for example, you'd get this error
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property message2 of bean class [org.example.TestBean]: Bean property message2 is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
After removing <property>, declare an appropriate bean to inject
<bean id="message2" class="java.lang.String">
<constructor-arg value="Helllo world!"/>
</bean>
You'll also need
<context:annotation-config />
to register the AutowiredAnnotationBeanPostProcessor that handles processing of #Autowired.
Note that declaring a String bean is awkward. You'd be better served by using the <property> or some property resolution mechanism that pulls the value from a config file and assigns it through a #Value annotated field.
#Value("${config.message2}")
private String message2;
parent class is like this:
public class BaseDAO{
private DBRoute defaultDB;
public DBRoute getDefaultDB()
{
return this.defaultDB;
}
public void setDefaultDB(DBRoute defaultDB)
{
this.defaultDB = defaultDB;
}
}
I have create beans like below:
<bean id="adsConfigDB" class="net.flyingfat.common.dbroute.config.DBRoute">
<constructor-arg value="adsConfig" />
</bean>
<bean id="adsBizDateDB" class="net.flyingfat.common.dbroute.config.DBRoute">
<constructor-arg value="adsBizDate" />
</bean>
I want to inject superclass property defaultDB in subclass through byName, not byType, which is in subclass inject defaultDB using adsConfigDB or adsBizDateDB. Is there any way to do this with spring annotations? I already tried Autowired or Resource with constructor which doesn't work. By the way, I already know this can be done using XML.
#Qualifier annotation – This annotation is used to avoid conflicts in bean mapping and we need to provide the bean name that will be used for autowiring. This way we can avoid issues where multiple beans are defined for same type. This annotation usually works with the #Autowired annotation. For constructors with multiple arguments, we can use this annotation with the argument names in the method.
Your code will be like this..
#Autowired
#Qualifier("adsConfig")
private DBRoute defaultDB;
How do I inject a String into a class. I Have seen plenty of examples of how to inject a class but can't find any for a String.
An example: If your field is called "name" and your class is called "Person" you can use setter injection like this:
<bean id="personBean" class="example.Person">
<property name="name" value="Paul" />
</bean>
It should be as simple as that. You will obviously need setter methods in your Person class for name.
Let Spring know where to find your properties file (in this case myProperties.properties):
<!-- Spring will replace ${} keys with values from the file used by the propertyConfigurer -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="location" value="classpath:myProperties.properties"/>
</bean>
In your class, you can inject like this:
#Value("${web.theme}")
private String theme;
In this case, the property defined bye "web.theme" in myProperties.properties will be injected into the "theme" member variable. But you can also inject in the constructor or setter as well.
If you don't want to use annotations, you can use it in your xml file as well.
I need to wire external lib class to my bean,in order to use it as singleton.
.xml config:
<bean id="myBean" class="com.my.MyBean">
<property name="someLib" value="com.ExternalBean" />
</bean>
java bean:
#Service
public class MyBean {
#Autowired
private ExternalBean externalBean;
public void setExternalBean(ExternalBean externalBean) {
this.externalBean = externalBean;
}
Further I use wired variable externalBean in public method ,in order not to instantiate it in every method call.
Problem is it null.
Do I wire bean correctly?What is mistake.
You have to define the external class as a bean in order to make #Autowired work.
<bean id="externalBean" class="some.external.package.ExternalBean">
</bean>
<bean id="myBean" class="com.my.MyBean">
</bean>
Also, if you use #Autowired you don't need the setter for it.
loodakrawa is right. A second thing that can cause a problem is, that you have a xml bean declaration for myBean and additional annotated the bean with #Service. I guess this will cause trouble as soon as use enable component scan.
I think that the better ide ais to use context path scan:
<context:component-scan base-package="some.external.package">
</context:component-scan>
Make sure that all these classes are within the package. Then mark both classes with one of the Annotations (#Repository, #Service, #Component).
One of the benefits, no setter required.
P.S: If you re using scan base you don't need to declare class as bean, annotations are enough
I have the following defined.
#Autowired
DaoType1<object1> someDao;
#Autowired
DaoType1<object1> someListDao;
and in my bean definitions I have two beans of the same type
<bean id="someDao" class="com.example.DaoType1" />
<bean id="someListDao" class="com.example.DaoType1" />
The second bean is imported from another xml file if that makes a difference. They have different properties being set as well. Why is spring not throwing an error because 2 beans of the same type have been defined. Does it use the variable names since they match the bean ids. The dao's are different and the functionality works as expected if I had used #Qualifiers for the two different beans.
Here is a more concise version. I've left out other beans since I they are not relevant.
applicationContext.xml
<import resource="classpath:dm-services-crud.xml"/>
<bean id="ruleListCrudService" class="com.idna.dm.service.crud.impl.RuleCrudServiceImpl">
<property name="crudDao" ref="ruleListCrudDao" />
</bean>
dm-services-crud.xml
<bean id="ruleCrudService" class="com.idna.dm.service.crud.impl.RuleCrudServiceImpl">
<property name="crudDao" ref="ruleCrudDao" />
<property name="ruleNetworkOfNodesCrudService" ref="ruleNetworkOfNodesCrudService" />
<property name="elementMappingsCrudService" ref="elementMappingsCrudService" />
<property name="ruleCrudDao" ref="newRuleCrudDao"/>
</bean>
default-autowire is not present in any of my xml files at all.
This appears to be expected behaviour. The documentation says:
byName
Autowiring by property name. Spring looks for a bean with the same name as the property that needs to be autowired. For example, if a bean definition is set to autowire by name, and it contains a master property (that is, it has a setMaster(..) method), Spring looks for a bean definition named master, and uses it to set the property.
I guess this means you have specified default-autowire="byName" in your applicationContext.xml.
However, refactoring may affect this in an unpredictable way. That's why (I think) it is advisable to switch to autowiring by type, and disambiguate the beans by the use of
#Qualifier (as you noted)
#Resource rather than #Autowired (as skaffman noted)
The #Autowired annotation behaves slightly differently to the "autowire by type" specification on xml based bean definitions.
When using annotations you're not technically doing an auto wire... you're setting the value based on the annotation. The autowire annotation has the same function as the xml property element.