Можно сделать это в Spring 3 с помощью поддержки EL. Пример:
@Value("#{systemProperties.databaseName}")
public void setDatabaseName(String dbName) { ... }
@Value("#{strategyBean.databaseKeyGenerator}")
public void setKeyGenerator(KeyGenerator kg) { ... }
systemProperties
неявный объект, и strategyBean
бобовое имя.
Еще один пример, который работает, когда Вы хотите захватить свойство от Properties
объект. Это также показывает, что можно подать заявку @Value
к полям:
@Value("#{myProperties['github.oauth.clientId']}")
private String githubOauthClientId;
Вот сообщение в блоге , я записал об этом для немного большего количества информации
Возможные решения состоят в том, чтобы объявить второй боб, который читает из того же файла свойств:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="/WEB-INF/app.properties" />
</bean>
<util:properties id="appProperties" location="classpath:/WEB-INF/app.properties"/>
боб, названный 'appProperties', имеет тип java.util. Свойства и могут быть введенным использованием зависимости @Resource attruibute показанный выше.
Прежде чем мы получим Spring 3 - который позволяет Вам вводить константы свойства непосредственно в Ваши бобы с помощью аннотаций - я записал подкласс боба PropertyPlaceholderConfigurer, который делает то же самое. Так, можно повысить методы set свойства, и Spring автосоединит свойства проводом в бобы как так:
@Property(key="property.key", defaultValue="default")
public void setProperty(String property) {
this.property = property;
}
Аннотация следующие:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface Property {
String key();
String defaultValue() default "";
}
PropertyAnnotationAndPlaceholderConfigurer следующие:
public class PropertyAnnotationAndPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
private static Logger log = Logger.getLogger(PropertyAnnotationAndPlaceholderConfigurer.class);
@Override
protected void processProperties(ConfigurableListableBeanFactory beanFactory, Properties properties) throws BeansException {
super.processProperties(beanFactory, properties);
for (String name : beanFactory.getBeanDefinitionNames()) {
MutablePropertyValues mpv = beanFactory.getBeanDefinition(name).getPropertyValues();
Class clazz = beanFactory.getType(name);
if(log.isDebugEnabled()) log.debug("Configuring properties for bean="+name+"["+clazz+"]");
if(clazz != null) {
for (PropertyDescriptor property : BeanUtils.getPropertyDescriptors(clazz)) {
Method setter = property.getWriteMethod();
Method getter = property.getReadMethod();
Property annotation = null;
if(setter != null && setter.isAnnotationPresent(Property.class)) {
annotation = setter.getAnnotation(Property.class);
} else if(setter != null && getter != null && getter.isAnnotationPresent(Property.class)) {
annotation = getter.getAnnotation(Property.class);
}
if(annotation != null) {
String value = resolvePlaceholder(annotation.key(), properties, SYSTEM_PROPERTIES_MODE_FALLBACK);
if(StringUtils.isEmpty(value)) {
value = annotation.defaultValue();
}
if(StringUtils.isEmpty(value)) {
throw new BeanConfigurationException("No such property=["+annotation.key()+"] found in properties.");
}
if(log.isDebugEnabled()) log.debug("setting property=["+clazz.getName()+"."+property.getName()+"] value=["+annotation.key()+"="+value+"]");
mpv.addPropertyValue(property.getName(), value);
}
}
for(Field field : clazz.getDeclaredFields()) {
if(log.isDebugEnabled()) log.debug("examining field=["+clazz.getName()+"."+field.getName()+"]");
if(field.isAnnotationPresent(Property.class)) {
Property annotation = field.getAnnotation(Property.class);
PropertyDescriptor property = BeanUtils.getPropertyDescriptor(clazz, field.getName());
if(property.getWriteMethod() == null) {
throw new BeanConfigurationException("setter for property=["+clazz.getName()+"."+field.getName()+"] not available.");
}
Object value = resolvePlaceholder(annotation.key(), properties, SYSTEM_PROPERTIES_MODE_FALLBACK);
if(value == null) {
value = annotation.defaultValue();
}
if(value == null) {
throw new BeanConfigurationException("No such property=["+annotation.key()+"] found in properties.");
}
if(log.isDebugEnabled()) log.debug("setting property=["+clazz.getName()+"."+field.getName()+"] value=["+annotation.key()+"="+value+"]");
mpv.addPropertyValue(property.getName(), value);
}
}
}
}
}
}
Не стесняются изменять для дегустации
У меня должно быть два файла свойств, один для производства и переопределения для разработки (который не будет развернут).
Для имения обоих, Боб Свойств, который может быть автосоединен проводом и PropertyConfigurer, можно записать:
<bean id="appProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="singleton" value="true" />
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<value>classpath:live.properties</value>
<value>classpath:development.properties</value>
</list>
</property>
</bean>
и ссылка Боб Свойств в PropertyConfigurer
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="appProperties" />
</bean>
Другая альтернатива должна добавить appProperties боб, показанный ниже:
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="/WEB-INF/app.properties" />
</bean>
<bean id="appProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="singleton" value="true"/>
<property name="properties">
<props>
<prop key="results.max">${results.max}</prop>
</props>
</property>
</bean>
, Когда получено, этот боб может быть брошен к java.util.Properties
, который будет содержать свойство, названное results.max
, чье значение читается от app.properties
. Снова, этот боб может быть введенной зависимостью (как экземпляр java.util. Свойства) в любой класс с помощью @Resource аннотации.
Лично, я предпочитаю это решение (к другому, я сделал предложение), поскольку можно ограничить точно, какие свойства представлены appProperties и не должны читать app.properties дважды.
В добавлена новая аннотация @Value
Пружина 3.0.0M3 . @Value
поддерживает не только выражения # {...}
, но и $ {...}
заполнители
Если вы застряли при использовании Spring 2.5, вы можете определить bean-компонент для каждого из ваших свойств и внедрить их с помощью квалификаторов. Примерно так:
<bean id="someFile" class="java.io.File">
<constructor-arg value="${someFile}"/>
</bean>
и
@Service
public class Thing
public Thing(@Qualifier("someFile") File someFile) {
...
Он не очень удобочитаемый, но выполняет свою работу.