Actually if you need only to read properties from a file and not to use these properties in Spring's property placeholders, then the solution is simple
public class Test1 {
@Autowired
Properties props;
public void printProps() {
for(Entry<Object, Object> e : props.entrySet()) {
System.out.println(e);
}
}
...
<util:properties id="props" location="/spring.properties" />
Answer from Evgeniy Dorofeev on Stack OverflowActually if you need only to read properties from a file and not to use these properties in Spring's property placeholders, then the solution is simple
public class Test1 {
@Autowired
Properties props;
public void printProps() {
for(Entry<Object, Object> e : props.entrySet()) {
System.out.println(e);
}
}
...
<util:properties id="props" location="/spring.properties" />
The @Value mechanism works through the PropertyPlaceholderConfigurer which is in turn a BeanFactoryPostProcessor. The properties used by it are not exposed at runtime. See this previous answer of mine for a possible solution.
You can pass an InputStream to the Property, so your file can pretty much be anywhere, and called anything.
Properties properties = new Properties();
try {
properties.load(new FileInputStream("path/filename"));
} catch (IOException e) {
...
}
Iterate as:
for(String key : properties.stringPropertyNames()) {
String value = properties.getProperty(key);
System.out.println(key + " => " + value);
}
You can store the file anywhere you like. If you want to keep it in your jar file, you'll want to use
Class.getResourceAsStream()orClassLoader.getResourceAsStream()to access it. If it's on the file system it's slightly easier.Any extension is fine, although .properties is more common in my experience
Load the file using
Properties.load, passing in anInputStreamor aStreamReaderif you're using Java 6. (If you are using Java 6, I'd probably use UTF-8 and aReaderinstead of the default ISO-8859-1 encoding for a stream.)Iterate through it as you'd iterate through a normal
Hashtable(whichPropertiesderives from), e.g. usingkeySet(). Alternatively, you can use the enumeration returned bypropertyNames().
keywordsList.addAll(Arrays.asList(prop.getProperty("keywordsList").split(","));
Should work.
Properties extends HashTable implements Map, so you can get all the keys as a Set<String> using keySet().
Any property value is a String. You can split the String given a delimiter.
If you're asking how to add that Object back into the Properties, the answer is "you can't". Properties uses a String key and a String value. If you want multi-map behavior (String key, List value), you'll have to implement your own.
There is no linguistic support to do what you're asking for.
You can reflectively access the members of a type at run-time using reflection (e.g. with Class.getDeclaredFields() to get an array of Field), but depending on what you're trying to do, this may not be the best solution.
See also
- Java Tutorials: Reflection API / Advanced Language Topics: Reflection
Related questions
- What is reflection, and why is it useful?
- Java Reflection: Why is it so bad?
- How could Reflection not lead to code smells?
- Dumping a java object’s properties
Example
Here's a simple example to show only some of what reflection is capable of doing.
import java.lang.reflect.*;
public class DumpFields {
public static void main(String[] args) {
inspect(String.class);
}
static <T> void inspect(Class<T> klazz) {
Field[] fields = klazz.getDeclaredFields();
System.out.printf("%d fields:%n", fields.length);
for (Field field : fields) {
System.out.printf("%s %s %s%n",
Modifier.toString(field.getModifiers()),
field.getType().getSimpleName(),
field.getName()
);
}
}
}
The above snippet uses reflection to inspect all the declared fields of class String; it produces the following output:
7 fields:
private final char[] value
private final int offset
private final int count
private int hash
private static final long serialVersionUID
private static final ObjectStreamField[] serialPersistentFields
public static final Comparator CASE_INSENSITIVE_ORDER
Effective Java 2nd Edition, Item 53: Prefer interfaces to reflection
These are excerpts from the book:
Given a
Classobject, you can obtainConstructor,Method, andFieldinstances representing the constructors, methods and fields of the class. [They] let you manipulate their underlying counterparts reflectively. This power, however, comes at a price:
- You lose all the benefits of compile-time checking.
- The code required to perform reflective access is clumsy and verbose.
- Performance suffers.
As a rule, objects should not be accessed reflectively in normal applications at runtime.
There are a few sophisticated applications that require reflection. Examples include [...omitted on purpose...] If you have any doubts as to whether your application falls into one of these categories, it probably doesn't.
Accessing the fields directly is not really good style in java. I would suggest creating getter and setter methods for the fields of your bean and then using then Introspector and BeanInfo classes from the java.beans package.
MyBean bean = new MyBean();
BeanInfo beanInfo = Introspector.getBeanInfo(MyBean.class);
for (PropertyDescriptor propertyDesc : beanInfo.getPropertyDescriptors()) {
String propertyName = propertyDesc.getName();
Object value = propertyDesc.getReadMethod().invoke(bean);
}