Как я могу ввести значение свойства в Боб Spring, который был настроен с помощью аннотаций?

284
задан Peter Mularien 25 January 2013 в 04:05
поделиться

7 ответов

Можно сделать это в 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;

Вот сообщение в блоге , я записал об этом для немного большего количества информации

289
ответ дан FrankerZ 23 November 2019 в 01:52
поделиться

Возможные решения состоят в том, чтобы объявить второй боб, который читает из того же файла свойств:

<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 показанный выше.

5
ответ дан Dónal 23 November 2019 в 01:52
поделиться

Прежде чем мы получим 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);
                    }
                }
            }
        }
    }

}

Не стесняются изменять для дегустации

7
ответ дан Ricardo Gladwell 23 November 2019 в 01:52
поделиться

У меня должно быть два файла свойств, один для производства и переопределения для разработки (который не будет развернут).

Для имения обоих, Боб Свойств, который может быть автосоединен проводом и 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>
9
ответ дан Willi aus Rohr 23 November 2019 в 01:52
поделиться

Другая альтернатива должна добавить 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 дважды.

15
ответ дан davek 23 November 2019 в 01:52
поделиться

В добавлена ​​новая аннотация @Value Пружина 3.0.0M3 . @Value поддерживает не только выражения # {...} , но и $ {...} заполнители

120
ответ дан 23 November 2019 в 01:52
поделиться

Если вы застряли при использовании 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) {
...

Он не очень удобочитаемый, но выполняет свою работу.

3
ответ дан 23 November 2019 в 01:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: