I suspect you have a design issue to have this requirement however.
The only way around this is I can think of is to make your properties ThreadLocal.
public class ThreadLocalProperties extends Properties {
private final ThreadLocal<Properties> localProperties = new ThreadLocal<Properties>() {
@Override
protected Properties initialValue() {
return new Properties();
}
};
public ThreadLocalProperties(Properties properties) {
super(properties);
}
@Override
public String getProperty(String key) {
String localValue = localProperties.get().getProperty(key);
return localValue == null ? super.getProperty(key) : localValue;
}
@Override
public Object setProperty(String key, String value) {
return localProperties.get().setProperty(key, value);
}
}
// Make the properties thread local from here. This to be done globally once.
System.setProperties(new ThreadLocalProperties(System.getProperties()));
// in each thread.
System.setProperty("javax.net.ssl.keyStore", "my-key-store");
Unless there is any confusion, System.setProperties() doesn't just set properties, it replaces the collection, and its implementation.
// From java.lang.System
* The argument becomes the current set of system properties for use
* by the {@link #getProperty(String)} method.
public static void setProperties(Properties props) {
SecurityManager sm = getSecurityManager();
if (sm != null) {
sm.checkPropertiesAccess();
}
if (props == null) {
props = new Properties();
initProperties(props);
}
System.props = props;
}
By using this method the behaviour of System Properties changes to being thread local for calls to setProperty() and getProperty()
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…