Reputation: 92019
I have following situation
- Have a MongoService class, which reads host, port, database from file
xml configuration
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>file:///storage/local.properties</value>
</list>
</property>
</bean>
</beans>
The local.properties looks like
### === MongoDB interaction === ###
host="127.0.0.1"
port=27017
database=contract
and MongoService Class as
@Service
public class MongoService {
private final Mongo mongo;
private final String database;
private static final Logger LOGGER = LoggerFactory.getLogger(MongoService.class);
public MongoService(@Nonnull final @Value("#{ systemProperties['host']}") String host, @Nonnull final @Value("#{ systemProperties['port']}") int port, @Nonnull final @Value("#{ systemProperties['database']}") String db) throws UnknownHostException {
LOGGER.info("host=" + host + ", port=" + port + ", database=" + db);
mongo = new Mongo(host, port);
database = db;
}
}
When I want to test that bean is fine, I do the following in
MongoServiceTest.java
public class MongoServiceTest {
@Autowired
private MongoService mongoService;
}
It complains saying that can not identify bean for MongoService
.
Then I add the following to above xml
<bean id="mongoService" class="com.business.persist.MongoService"></bean>
Then it complains saying "No Matching Constructor found"
What I want to do
a.) MongoService should be @Autowired
and reads configuration params from <value>file:///storage/local.properties</value>
Question
a.) Is accessing values in constructor are correct? (file name is local.properties and I am using @Value("#{ systemProperties['host']}") syntax)
b.) What is that I need to make it work so that @Autowired private MongoService mongoService
loads correctly and reads value off local.properties file.
P.S. I am very new to Spring and don't really know how to make this work
Thanks much for your help in advance
Upvotes: 3
Views: 4170
Reputation: 4249
I think , You have to add constructor-arg to config xml as follows.
<bean id="mongoService" class="com.business.persist.MongoService">
<constructor-arg type="java.lang.String">
<value>host</value>
</constructor-arg>
<constructor-arg type="int">
<value>port</value>
</constructor-arg>
<constructor-arg type="java.lang.String">
<value>database</value>
</constructor-arg>
</bean>
I am not sure,Bst way could be adding java based bean config. Remove the bean definition from xml and add java-based congfig as follows
@Service
public class MongoService {
private final Mongo mongo;
private final String database;
private static final Logger LOGGER = LoggerFactory.getLogger(MongoService.class);
@bean
public MongoService(@Nonnull final @Value("#{ systemProperties['host']}") String host, @Nonnull final @Value("#{ systemProperties['port']}") int port, @Nonnull final @Value("#{ systemProperties['database']}") String db) throws UnknownHostException {
LOGGER.info("host=" + host + ", port=" + port + ", database=" + db);
mongo = new Mongo(host, port);
database = db;
}
}
HTH
Upvotes: 2
Reputation: 45253
By default, Spring instantiates objects using the default constructor (with no args) and then uses the setter methods to set all the properies. If you don't want to (or can't) use the setters or define a default construtor, you have to tell spring what to pass in as constructor args.
Here is a blog post explaining how it can be done:
http://www.javalobby.org/java/forums/t18396.html
The basic syntax looks like this:
<bean name="MyBean" class="com.example.BeanClass">
<constructor-arg index="0"><ref bean="OtherBeanName"/></constructor-arg>
</bean>
The index attribute is optional but it requires you to order the XML constructor-arg
elements in the same order as the params to the constructor.
Upvotes: 0