以下のコードを使用して、Spring Beanにプロパティファイルのプロパティを注入します。
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="classpath:/my.properties"/>
</bean>
<bean id="blah" class="abc">
<property name="path" value="${the.path}"/>
</bean>
プログラムでプロパティにアクセスする方法はありますか?私は依存性注入なしでいくつかのコードを実行しようとしています。だから私はこのようないくつかのコードが欲しいだけです:
PropertyPlaceholderConfigurer props = new PropertyPlaceholderConfigurer();
props.load("classpath:/my.properties");
props.get("path");
PropertiesLoaderUtils についてはどうですか?
Resource resource = new ClassPathResource("/my.properties");
Properties props = PropertiesLoaderUtils.loadProperties(resource);
コードからプレースホルダー値にアクセスするだけであれば、@Value
アノテーションがあります。
@Value("${settings.some.property}")
String someValue;
SPELからプレースホルダーにアクセスするには、次の構文を使用します。
#('${settings.some.property}')
SPELがオフになっているビューに構成を公開するには、次のトリックを使用できます。
package com.my.app;
import Java.util.Collection;
import Java.util.Map;
import Java.util.Set;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.stereotype.Component;
@Component
public class PropertyPlaceholderExposer implements Map<String, String>, BeanFactoryAware {
ConfigurableBeanFactory beanFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = (ConfigurableBeanFactory) beanFactory;
}
protected String resolveProperty(String name) {
String rv = beanFactory.resolveEmbeddedValue("${" + name + "}");
return rv;
}
@Override
public String get(Object key) {
return resolveProperty(key.toString());
}
@Override
public boolean containsKey(Object key) {
try {
resolveProperty(key.toString());
return true;
}
catch(Exception e) {
return false;
}
}
@Override public boolean isEmpty() { return false; }
@Override public Set<String> keySet() { throw new UnsupportedOperationException(); }
@Override public Set<Java.util.Map.Entry<String, String>> entrySet() { throw new UnsupportedOperationException(); }
@Override public Collection<String> values() { throw new UnsupportedOperationException(); }
@Override public int size() { throw new UnsupportedOperationException(); }
@Override public boolean containsValue(Object value) { throw new UnsupportedOperationException(); }
@Override public void clear() { throw new UnsupportedOperationException(); }
@Override public String put(String key, String value) { throw new UnsupportedOperationException(); }
@Override public String remove(Object key) { throw new UnsupportedOperationException(); }
@Override public void putAll(Map<? extends String, ? extends String> t) { throw new UnsupportedOperationException(); }
}
そして、エクスポーザーを使用して、プロパティをビューに公開します。
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" id="tilesViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
<property name="attributesMap">
<map>
<entry key="config">
<bean class="com.my.app.PropertyPlaceholderExposer" />
</entry>
</map>
</property>
</bean>
次に、ビューで、次のような公開プロパティを使用します。
${config['settings.some.property']}
このソリューションには、context:property-placeholderタグによって挿入された標準のプレースホルダー実装に依存できるという利点があります。
最後の注意点として、すべてのプレースホルダープロパティとその値をキャプチャする必要がある場合、それらをStringValueResolverにパイプして、プレースホルダーがプロパティ値内で期待どおりに動作することを確認する必要があります。次のコードはそれを行います。
package com.my.app;
import Java.util.Collection;
import Java.util.HashMap;
import Java.util.Map;
import Java.util.Properties;
import Java.util.Set;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.util.StringValueResolver;
public class AppConfig extends PropertyPlaceholderConfigurer implements Map<String, String> {
Map<String, String> props = new HashMap<String, String>();
@Override
protected void processProperties(ConfigurableListableBeanFactory beanFactory, Properties props)
throws BeansException {
this.props.clear();
for (Entry<Object, Object> e: props.entrySet())
this.props.put(e.getKey().toString(), e.getValue().toString());
super.processProperties(beanFactory, props);
}
@Override
protected void doProcessProperties(ConfigurableListableBeanFactory beanFactoryToProcess,
StringValueResolver valueResolver) {
super.doProcessProperties(beanFactoryToProcess, valueResolver);
for(Entry<String, String> e: props.entrySet())
e.setValue(valueResolver.resolveStringValue(e.getValue()));
}
// Implement map interface to access stored properties
@Override public Set<String> keySet() { return props.keySet(); }
@Override public Set<Java.util.Map.Entry<String, String>> entrySet() { return props.entrySet(); }
@Override public Collection<String> values() { return props.values(); }
@Override public int size() { return props.size(); }
@Override public boolean isEmpty() { return props.isEmpty(); }
@Override public boolean containsValue(Object value) { return props.containsValue(value); }
@Override public boolean containsKey(Object key) { return props.containsKey(key); }
@Override public String get(Object key) { return props.get(key); }
@Override public void clear() { throw new UnsupportedOperationException(); }
@Override public String put(String key, String value) { throw new UnsupportedOperationException(); }
@Override public String remove(Object key) { throw new UnsupportedOperationException(); }
@Override public void putAll(Map<? extends String, ? extends String> t) { throw new UnsupportedOperationException(); }
}
CREDIT: プロパティファイルを再読み込みせずにSpringのプロパティにプログラムでアクセス
私は、スプリングが既にロードしたものと同じプロパティをリロードすることなく、スプリングでプロパティにアクセスするニースの実装を見つけました。 [また、ソース内のプロパティファイルの場所をハードコードする必要はありません]
これらの変更により、コードはよりクリーンでメンテナンスしやすくなります。
コンセプトは非常にシンプルです。スプリングのデフォルトプロパティプレースホルダー(PropertyPlaceholderConfigurer)を拡張し、ロードするプロパティをローカル変数にキャプチャするだけです
public class SpringPropertiesUtil extends PropertyPlaceholderConfigurer {
private static Map<String, String> propertiesMap;
// Default as in PropertyPlaceholderConfigurer
private int springSystemPropertiesMode = SYSTEM_PROPERTIES_MODE_FALLBACK;
@Override
public void setSystemPropertiesMode(int systemPropertiesMode) {
super.setSystemPropertiesMode(systemPropertiesMode);
springSystemPropertiesMode = systemPropertiesMode;
}
@Override
protected void processProperties(ConfigurableListableBeanFactory beanFactory, Properties props) throws BeansException {
super.processProperties(beanFactory, props);
propertiesMap = new HashMap<String, String>();
for (Object key : props.keySet()) {
String keyStr = key.toString();
String valueStr = resolvePlaceholder(keyStr, props, springSystemPropertiesMode);
propertiesMap.put(keyStr, valueStr);
}
}
public static String getProperty(String name) {
return propertiesMap.get(name).toString();
}
}
使用例
SpringPropertiesUtil.getProperty("myProperty")
Spring設定の変更
<bean id="placeholderConfigMM" class="SpringPropertiesUtil">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="locations">
<list>
<value>classpath:myproperties.properties</value>
</list>
</property>
</bean>
これがあなたの抱えている問題の解決に役立つことを願っています
私はこれをやったが、うまくいった。
Properties props = PropertiesLoaderUtils.loadAllProperties("my.properties");
PropertyPlaceholderConfigurer props2 = new PropertyPlaceholderConfigurer();
props2.setProperties(props);
うまくいくはずです。
Spring utilsを使用するか、PropertiesFactoryBeanを介してプロパティをロードすることもできます。
<util:properties id="myProps" location="classpath:com/foo/myprops.properties"/>
または:
<bean id="myProps" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:com/foo/myprops.properties"/>
</bean>
次に、アプリケーションでそれらを選択できます。
@Resource(name = "myProps")
private Properties myProps;
さらに、設定で次のプロパティを使用します。
<context:property-placeholder properties-ref="myProps"/>
これはドキュメントにもあります: http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#xsd-config-body-schemas-util-properties
以下のようなクラスを作成します
package com.tmghealth.common.util;
import Java.util.Properties;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
@Configuration
@PropertySource(value = { "classpath:/spring/server-urls.properties" })
public class PropertiesReader extends PropertyPlaceholderConfigurer {
@Override
protected void processProperties(
ConfigurableListableBeanFactory beanFactory, Properties props)
throws BeansException {
super.processProperties(beanFactory, props);
}
}
その後、プロパティにアクセスしたい場所で使用します
@Autowired
private Environment environment;
and getters and setters then access using
environment.getProperty(envName
+ ".letter.fdi.letterdetails.restServiceUrl");
-アクセサークラスでゲッターとセッターを記述する
public Environment getEnvironment() {
return environment;
}`enter code here`
public void setEnvironment(Environment environment) {
this.environment = environment;
}
ご存知のように、Springの新しいバージョンはPropertyPlaceholderConfigurerを使用せず、PropertySourcesPlaceholderConfigurerと呼ばれる別の悪夢のような構成を使用します。コードから解決されたプロパティを取得しようとしていて、Springチームがずっと前にこれを行う方法を提供してくれたら、この投稿に投票してください! ...これは、新しい方法で行うためです。
サブクラスPropertySourcesPlaceholderConfigurer:
public class SpringPropertyExposer extends PropertySourcesPlaceholderConfigurer {
private ConfigurableListableBeanFactory factory;
/**
* Save off the bean factory so we can use it later to resolve properties
*/
@Override
protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess,
final ConfigurablePropertyResolver propertyResolver) throws BeansException {
super.processProperties(beanFactoryToProcess, propertyResolver);
if (beanFactoryToProcess.hasEmbeddedValueResolver()) {
logger.debug("Value resolver exists.");
factory = beanFactoryToProcess;
}
else {
logger.error("No existing embedded value resolver.");
}
}
public String getProperty(String name) {
Object propertyValue = factory.resolveEmbeddedValue(this.placeholderPrefix + name + this.placeholderSuffix);
return propertyValue.toString();
}
}
これを使用するには、必ず@Configurationでサブクラスを使用し、後で使用できるようにサブクラスへの参照を保存してください。
@Configuration
@ComponentScan
public class PropertiesConfig {
public static SpringPropertyExposer commonEnvConfig;
@Bean(name="commonConfig")
public static PropertySourcesPlaceholderConfigurer commonConfig() throws IOException {
commonEnvConfig = new SpringPropertyExposer(); //This is a subclass of the return type.
PropertiesFactoryBean commonConfig = new PropertiesFactoryBean();
commonConfig.setLocation(new ClassPathResource("META-INF/spring/config.properties"));
try {
commonConfig.afterPropertiesSet();
}
catch (IOException e) {
e.printStackTrace();
throw e;
}
commonEnvConfig.setProperties(commonConfig.getObject());
return commonEnvConfig;
}
}
使用法:
Object value = PropertiesConfig.commonEnvConfig.getProperty("key.subkey");
これは私を助けます:
ApplicationContextUtils.getApplicationContext().getEnvironment()
ここに別のサンプルがあります。
XmlBeanFactory factory = new XmlBeanFactory(new FileSystemResource("beans.xml"));
PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
cfg.setLocation(new FileSystemResource("jdbc.properties"));
cfg.postProcessBeanFactory(factory);
これにより、ネストされたプロパティが解決されます。
public class Environment extends PropertyPlaceholderConfigurer {
/**
* Map that hold all the properties.
*/
private Map<String, String> propertiesMap;
/**
* Iterate through all the Property keys and build a Map, resolve all the nested values before building the map.
*/
@Override
protected void processProperties(ConfigurableListableBeanFactory beanFactory, Properties props) throws BeansException {
super.processProperties(beanFactory, props);
propertiesMap = new HashMap<String, String>();
for (Object key : props.keySet()) {
String keyStr = key.toString();
String valueStr = beanFactory.resolveEmbeddedValue(placeholderPrefix + keyStr.trim() + DEFAULT_PLACEHOLDER_SUFFIX);
propertiesMap.put(keyStr, valueStr);
}
}
/**
* This method gets the String value for a given String key for the property files.
*
* @param name - Key for which the value needs to be retrieved.
* @return Value
*/
public String getProperty(String name) {
return propertiesMap.get(name).toString();
}
Environment
を挿入し、getPropertyを呼び出すだけです。
@Autowired
private Environment env;
void foo() {
env.getProperty("your.property");
}
この投稿では、プロパティへのアクセス方法も説明しています。 http://maciej-miklas.blogspot.de/2013/07/spring-31-programmatic-access-to.html
そのようなSpring Beanでspring property-placeholderによってロードされたプロパティにアクセスできます。
@Named
public class PropertiesAccessor {
private final AbstractBeanFactory beanFactory;
private final Map<String,String> cache = new ConcurrentHashMap<>();
@Inject
protected PropertiesAccessor(AbstractBeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
public String getProperty(String key) {
if(cache.containsKey(key)){
return cache.get(key);
}
String foundProp = null;
try {
foundProp = beanFactory.resolveEmbeddedValue("${" + key.trim() + "}");
cache.put(key,foundProp);
} catch (IllegalArgumentException ex) {
// ok - property was not found
}
return foundProp;
}
}
あなたのアプリケーションのクラスパスからファイルをロードするには、あなたのスプリング設定ファイルで以下のコードを使用してください
<context:property-placeholder
ignore-unresolvable="true" ignore-resource-not-found="false" location="classpath:property-file-name" />
これは私がそれを動作させるための最高の方法です:
package your.package;
import Java.io.IOException;
import Java.util.Properties;
import Java.util.logging.Level;
import Java.util.logging.Logger;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
public class ApplicationProperties {
private Properties properties;
public ApplicationProperties() {
// application.properties located at src/main/resource
Resource resource = new ClassPathResource("/application.properties");
try {
this.properties = PropertiesLoaderUtils.loadProperties(resource);
} catch (IOException ex) {
Logger.getLogger(ApplicationProperties.class.getName()).log(Level.SEVERE, null, ex);
}
}
public String getProperty(String propertyName) {
return this.properties.getProperty(propertyName);
}
}
Environment
クラスを介してプロパティを取得できます。ドキュメントの立場として:
プロパティは、ほとんどすべてのアプリケーションで重要な役割を果たし、プロパティファイル、JVMシステムプロパティ、システム環境変数、JNDI、サーブレットコンテキストパラメータ、アドホックプロパティオブジェクト、マップなど、さまざまなソースから生成される場合があります。プロパティに関連する環境オブジェクトの役割は、プロパティソースを構成し、プロパティソースからプロパティを解決するための便利なサービスインターフェイスをユーザーに提供することです。
環境をenv
変数として使用して、単に呼び出します:
env.resolvePlaceholders("${your-property:default-value}")
「生の」プロパティは次の方法で取得できます。
env.getProperty("your-property")
Springが登録したすべてのプロパティソースを検索します。
次の方法で環境を取得できます。
ApplicationContextAware
を実装してApplicationContextを注入し、コンテキストでgetEnvironment()
を呼び出すEnvironmentAware
を実装します。プロパティはBeanの構築に必要な場合があるため、プロパティはアプリケーションの起動の初期段階で解決されるため、クラスの実装を通じて取得されます。
ドキュメントの詳細: spring Environment documentation
create .properties file in classpath of your project and add path configuration in xml`<context:property-placeholder location="classpath*:/*.properties" />`
servlet-context.xmlの後、どこでもファイルを直接使用できます