当前位置:  开发笔记 > 编程语言 > 正文

如何将属性值注入使用注释配置的Spring Bean?

如何解决《如何将属性值注入使用注释配置的SpringBean?》经验,为你挑选了11个好方法。

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

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

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


    
 

我想将app.properites中的一个属性注入上面显示的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



1> Willie Wheel..:

您可以在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;

这是一篇关于这篇文章的博客文章,以获取更多信息.


确保从max的答案中注意到你也可以在表达式$ {db.doStuff}中使用占位符,然后你不需要一个PropertiesFactoryBean,只需一个placeholderConfigurer
您可以使用util:properties添加自己的属性; 例如,.有关如何获取值的信息,请参阅已编辑的答案.(我意识到这可能为时已晚,不能对Don有所帮助,但其他人希望会受益.)
`systemProperties`只是`System.getProperties()`?我想如果我想将自己的属性注入Spring bean,我需要定义一个``然后从中读取值到另一个bean使用类似`@Value("#{appProperties.databaseName}")`的东西
当我在appname-servlet.xml文件中使用util:properties时,它只适用于我.使用我的applicationContext.xml(而不是Spring MVC)中定义的propertyConfigurer不起作用.

2> barrymac..:

就个人而言,我喜欢文档中Spring 3.0的这种新方式:

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

没有吸气剂或安装者!

通过配置加载属性:


为了进一步让我高兴,我甚至可以控制IntelliJ中的EL表达式,它将我带到了属性定义!

还有完全非xml版本:

@PropertySource("classpath:propertyFile.properties")
public class AppConfig {

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }


确保并添加命名空间uri xmlns:p ="http://www.springframework.org/schema/p"以使用p:prefixed属性.
叹了口气,我花了一个小时试图只做注释工作,并且在阅读了这个魔法静态豆PropertySauceYadaYada的这个答案之后才发现了什么.春天的爱!
为什么这些方法在测试上下文中工作但在主上下文中不起作用?

3> 小智..:

有一个新的注释@Value春季3.0.0M3.@Value不仅支持#{...}表达式,还支持${...}占位符


+1如果示例有帮助,这里是 - @Value(value ="#{'$ {server.env}'}")或只是@Value("#{'$ {server.env}'}")

4> shane lee..:

是与PropertyPlaceholderConfigurer等效的XML.

示例:applicationContext.xml

  

组件类

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



5> Dónal..:

另一种方法是添加如下所示的appProperties bean:


        
 



        

        
                
                        ${results.max}
                
        

检索时,可以将此bean强制转换为java.util.Properties包含名称,results.max其值从中读取的属性app.properties.同样,这个bean可以通过@Resource注释依赖注入(作为java.util.Properties的一个实例)到任何类中.

就个人而言,我更喜欢这个解决方案(我提出的另一个解决方案),因为你可以准确地限制appProperties公开的属性,并且不需要两次读取app.properties.



6> 小智..:

我需要有两个属性文件,一个用于生产,一个用于开发的覆盖(不会被部署).

要同时拥有一个可以自动装配的属性Bean和一个PropertyConfigurer,您可以编写:


    

    
    
        
            classpath:live.properties
            classpath:development.properties
        
    

并引用PropertyConfigurer中的Properties Bean


    



7> Ricardo Glad..:

在我们获得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);
                    }
                }
            }
        }
    }

}

随意修改味道


请注意,我已为上述内容创建了一个新项目:http://code.google.com/p/spring-property-annotations/

8> hi.nitish..:

春天的方式:
private @Value("${propertyName}") String propertyField;

是使用Spring的"PropertyPlaceholderConfigurer"类注入值的新方法.另一种方式是打电话

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

注意:对于@Value,您不能使用静态 propertyField,它应该只是非静态的,否则返回null.要修复它,会为静态字段创建一个非静态setter,并在该setter上方应用@Value.



9> Alexis Gamar..:

你也可以注释你的课程:

@PropertySource("classpath:/com/myProject/config/properties/database.properties")

并有一个像这样的变量:

@Autowired
private Environment env;

现在,您可以通过以下方式访问所有属性:

env.getProperty("database.connection.driver")



10> Dónal..:

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


    
 


名为"appProperties"的bean的类型为java.util.Properties,可以使用上面显示的@Resource attruibute进行依赖注入.



11> Alireza Fatt..:

如上所述@Value,这项工作非常灵活,因为你可以使用弹簧EL.

以下是一些可能有用的示例:

//Build and array from comma separated parameters 
//Like currency.codes.list=10,11,12,13
@Value("#{'${currency.codes.list}'.split(',')}") 
private List currencyTypes;

另一个set来自一个list

//If you have a list of some objects like (List) 
//and the BranchVO has areaCode,cityCode,...
//You can easily make a set or areaCodes as below
@Value("#{BranchList.![areaCode]}") 
private Set areas;

您还可以设置基元类型的值.

@Value("${amount.limit}")
private int amountLimit;

你可以调用静态方法:

@Value("#{T(foo.bar).isSecurityEnabled()}")
private boolean securityEnabled;

你可以有逻辑

@Value("#{T(foo.bar).isSecurityEnabled() ? '${security.logo.path}' : '${default.logo.path}'}")
private String logoPath;

推荐阅读
ERIK又
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有