我有一堆Spring bean,它们是通过注释从类路径中获取的,例如。

@Repository("personDao")
public class PersonDaoImpl extends AbstractDaoImpl implements PersonDao {
    // Implementation omitted
}

在Spring XML文件中,定义了一个PropertyPlaceholderConfigurer:

<bean id="propertyConfigurer" 
  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="/WEB-INF/app.properties" />
</bean> 

我想将app. properties中的一个属性注入到上面所示的bean中。我不能简单地做一些

<bean class="com.example.PersonDaoImpl">
    <property name="maxResults" value="${results.max}"/>
</bean>

因为PersonDaoImpl没有出现在Spring XML文件中(它是通过注释从类路径中获取的)。我已经了解到以下内容:

@Repository("personDao")
public class PersonDaoImpl extends AbstractDaoImpl implements PersonDao {

    @Resource(name = "propertyConfigurer")
    protected void setProperties(PropertyPlaceholderConfigurer ppc) {
    // Now how do I access results.max? 
    }
}

但我不清楚我如何从ppc访问我感兴趣的财产?


当前回答

一个可能的解决方案是声明第二个bean,它从相同的属性文件中读取:

<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’的bean类型是java.util.Properties,可以使用上面所示的@Resource属性注入依赖项。

其他回答

一个可能的解决方案是声明第二个bean,它从相同的属性文件中读取:

<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’的bean类型是java.util.Properties,可以使用上面所示的@Resource属性注入依赖项。

<上下文:property-placeholder…/>是等价于PropertyPlaceholderConfigurer的XML。

例子: 中

<context:property-placeholder location="classpath:test.properties"/>  

组件类

 private @Value("${propertyName}") String propertyField;

您可以在Spring 3中使用EL支持来实现这一点。例子:

@Value("#{systemProperties.databaseName}")
public void setDatabaseName(String dbName) { ... }

@Value("#{strategyBean.databaseKeyGenerator}")
public void setKeyGenerator(KeyGenerator kg) { ... }

systemProperties是一个隐式对象,strategyBean是一个bean名称。

再举一个例子,当您想从Properties对象中获取属性时,它可以工作。它还显示了你可以对字段应用@Value:

@Value("#{myProperties['github.oauth.clientId']}")
private String githubOauthClientId;

这是我写的一篇关于这方面的博客文章,以获得更多信息。

春天道: 私人@ value (" $ {propertyName} ") 字符串propertyField;

是一种使用Spring的“PropertyPlaceholderConfigurer”类注入值的新方法。 另一种方法是打电话

java.util.Properties props = System.getProperties().getProperty("propertyName");

注意:对于@Value,你不能使用static propertyField,它只能是非静态的,否则它会返回null。为了解决这个问题,为静态字段创建了一个非静态setter,并在该setter之上应用@Value。

在我们得到Spring 3之前——它允许您使用注释直接将属性常量注入到bean中——我写了PropertyPlaceholderConfigurer bean的一个子类,它做同样的事情。所以,你可以标记你的属性设置,Spring会自动将你的属性连接到你的bean中,就像这样:

@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);
                    }
                }
            }
        }
    }

}

请随意修改口味