아래 코드를 사용하여 속성 파일의 속성으로 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(); }
}
답변
신용 : 속성 파일을 다시 읽지 않고 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")
스프링 구성 변경
<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);
작동합니다.
답변
스프링 유틸리티를 사용하거나 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");
-접근 자 클래스에서 getter 및 setter 작성
public Environment getEnvironment() {
return environment;
}`enter code here`
public void setEnvironment(Environment environment) {
this.environment = environment;
}
답변
최신 버전의 Spring은 PropertyPlaceholderConfigurer를 사용하지 않으며 이제 PropertySourcesPlaceholderConfigurer라는 또 다른 악몽 같은 구성을 사용합니다. 코드에서 해결 된 속성을 얻으려고 노력하고 스프링 팀이 오래 전에이 작업을 수행 할 수있는 방법을 원한다면이 게시물에 투표하십시오! … 이것이 새로운 방식으로 수행되기 때문에 :
서브 클래스 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");