Spring을 사용하여 속성 파일에 프로그래밍 방식으로 액세스하시겠습니까?
아래 코드를 사용하여 속성 파일에서 속성을 가진 스프링 콩을 주입합니다.
<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");
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(); }
}
나는 이것을 했고 효과가 있었다.
Properties props = PropertiesLoaderUtils.loadAllProperties("my.properties");
PropertyPlaceholderConfigurer props2 = new PropertyPlaceholderConfigurer();
props2.setProperties(props);
그러면 되겠군요.
크레디트: 봄에 속성 파일을 다시 읽지 않고 자산에 프로그래밍 방식으로 액세스할 수 있습니다.
스프링이 이미 로드한 속성을 다시 로드하지 않고도 봄에 프로그래밍 방식으로 속성에 액세스할 수 있는 훌륭한 구현을 발견했습니다.[또한 소스 내의 속성 파일 위치를 하드코드로 작성할 필요가 없습니다]
이러한 변경에 의해, 코드는 보다 깨끗하고 유지보수가 용이해 보입니다.
컨셉은 매우 간단합니다.스프링 기본 속성 자리 표시자(PropertyPlaceholderConfigr)를 확장하고 로컬 변수에 로드되는 속성을 캡처하기만 하면 됩니다.
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>
이것이 당신의 문제를 해결하는 데 도움이 되기를 바랍니다.
스프링 유틸리티를 사용하거나 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;
또한 Configuration에서 다음 속성을 사용합니다.
<context:property-placeholder properties-ref="myProps"/>
이는 문서 http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/ #xsd-config-body-schemas-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");
-- 접근자 클래스의 getters와 setters를 씁니다.
public Environment getEnvironment() {
return environment;
}`enter code here`
public void setEnvironment(Environment environment) {
this.environment = environment;
}
은 을 통해 수 .Environment
class. ★★★★★★★★
속성은 거의 모든 애플리케이션에서 중요한 역할을 하며 속성 파일, JVM 시스템 속성, 시스템 환경 변수, JNDI, 서블릿 컨텍스트 매개 변수, 애드혹 속성 개체, 맵 등 다양한 소스에서 발생할 수 있습니다.속성과 관련된 환경 개체의 역할은 속성 소스를 구성하고 속성에서 속성을 해결할 수 있는 편리한 서비스 인터페이스를 사용자에게 제공하는 것입니다.
을 「」로서 가지는 것env
콜: 변수, 단순 콜:
env.resolvePlaceholders("${your-property:default-value}")
다음을 통해 '원시' 속성을 얻을 수 있습니다.
env.getProperty("your-property")
스프링이 등록된 모든 속성 소스를 검색합니다.
다음 중 하나를 통해 환경을 얻을 수 있습니다.
- 하려면 Application Context를 해야 합니다.
ApplicationContextAware
에 전화해요.getEnvironment()
EnvironmentAware
.
속성들은 bean 구축에 필요할 수 있기 때문에 어플리케이션 부팅 초기에 해결되기 때문에 클래스 구현을 통해 얻을 수 있습니다.
아시다시피 Spring의 새로운 버전은 PropertyPlaceholderConfigr을 사용하지 않고 PropertySourcesPlaceholderConfigr이라는 악몽 같은 구조를 사용합니다.코드에서 해결된 속성을 얻으려면 Spring 팀이 오래 전에 이 작업을 수행할 수 있는 방법을 알려줬으면 합니다. 이 게시물에 투표하십시오.새로운 방법으로 이 작업을 수행할 수 있습니다.
하위 클래스 속성 소스 플레이스 홀더 구성:
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();
}
또, 이 투고에서는, 속성에의 액세스 방법에 대해서도 설명합니다.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;
}
}
이게 내가 작동시킨 가장 좋은 방법이야
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);
}
}
create .properties file in classpath of your project and add path configuration in xml`<context:property-placeholder location="classpath*:/*.properties" />`
그 후 servlet-syslog.xml로 파일을 직접 사용할 수 있습니다.
스프링 구성 파일에서 아래 코드를 사용하여 응용 프로그램의 클래스 경로에서 파일을 로드하십시오.
<context:property-placeholder
ignore-unresolvable="true" ignore-resource-not-found="false" location="classpath:property-file-name" />
오래된 스레드인 것은 알지만, 이 토픽은 "즉시" 로딩되는 마이크로 서비스가 필요하기 때문에 주석을 사용하지 않는 모든 사용 사례에 대해 기능적 접근 방식을 사용하는 사용자에게 매우 중요합니다.풀리지 않은 문제는 결국 내 application.yml에 있는 환경변수를 로드하는 것이었습니다.
public class AppPropsLoader {
public static Properties load() {
var propPholderConfig = new PropertySourcesPlaceHolderConfigurer();
var yaml = new YamlPropertiesFactoryBean();
ClassPathResource resource = new ClassPathResource("application.yml");
Objects.requireNonNull(resource, "File application.yml does not exist");
yaml.setResources(resource);
Objects.requireNonNull(yaml.getObject(), "Configuration cannot be null");
propPholderConfig.postProcessBeanFactory(new DefaultListableBeanFactory());
propPholderConfig.setProperties(yaml.getObject());
PropertySources appliedPropertySources =
propPholderConfig.getAppliedPropertySources();
var resolver = new PropertySourcesPlaceholderResolver(appliedPropertySources);
Properties resolvedProps = new Properties();
for (Map.Entry<Object, Object> prop: yaml.getObject().entrySet()) {
resolvedProps.setProperty((String)prop.getKey(),
getPropertyValue(resolver.resolvePlaceHolders(prop.getValue()));
}
return resolvedProps;
}
static String getPropertyValue(Object prop) {
var val = String.valueOf(prop);
Pattern p = Pattern.compile("^(\\$\\{)([a-zA-Z0-9-._]+)(\\})$");
Matcher m = p.matcher(val);
if(m.matches()) {
return System.getEnv(m.group(2));
}
return val;
}
}
언급URL : https://stackoverflow.com/questions/1771166/access-properties-file-programmatically-with-spring
'programing' 카테고리의 다른 글
세션 없이 Spring Security를 사용하려면 어떻게 해야 하나요? (0) | 2023.02.25 |
---|---|
redex 비동기 액션에 callBacks를 전달하는 것이 좋은 프랙티스로 간주됩니까? (0) | 2023.02.25 |
Angular에서 새 선을 보존하려면 어떻게 해야 합니까?JS 부분? (0) | 2023.02.25 |
플러그인 업로드 중 업로드된 파일이 php.ini 오류의 upload_max_filesize 지시문을 초과합니다. (0) | 2023.02.25 |
워드프레스는 표준 루프를 통해 투고 순서를 변경합니다. (0) | 2023.02.25 |