Spring 프로필에서 @PropertySources를 선택할 수 있습니까?
Spring 3.1이 있습니다.@Configuration
.foo
콩을 만드는 것.은 속은다정니다됩에 .defaults.properties
그나 속의재수있다니의 될 수 .overrides.properties
프로그램에 된 응용프에활상있는경우가가 있는 override
스프링 프로필.
오버라이드가 없다면 코드는 이렇게 보일 것이고 작동할 것입니다.
@Configuration
@PropertySource("classpath:defaults.properties")
public class MyConfiguration {
@Autowired
private Environment environment;
@Bean
public Bean bean() {
...
// this.environment.getRequiredProperty("foo");
...
}
}
나는 원합니다.@PropertySource
위해서classpath:overrides.properties
…에 @Profile("overrides")
이것이 어떻게 달성될 수 있는지에 대해 생각해 본 사람이 있습니까?한 옵션 된 옵션이 .@Configuration
DRY 입니다.ConfigurableEnvironment
하지만 어디에 있는지는 잘 모르겠습니다.environment.getPropertySources.addFirst()
전화가 끊겼습니다.
을 배치하는 로 직접 을 주입할 때 합니다.@Value
하지만 사용할 때는 그렇지 않습니다.Environment
리고그고.getRequiredProperty()
방법.
<context:property-placeholder ignore-unresolvable="true" location="classpath:defaults.properties"/>
<beans profile="overrides">
<context:property-placeholder ignore-unresolvable="true" order="0"
location="classpath:overrides.properties"/>
</beans>
갱신하다
지금 이 작업을 수행하려면 Spring Boot의 YAML 지원, 특히 'Properties 대신 YAML 사용' 섹션을 확인하십시오.프로필 지원을 통해 이 질문이 화제가 될 수 있지만, 그렇지 않습니다.@PropertySource
아직 지지하지 않습니다.
순위를 합니다.@PropertySource
정적인 내면의 계급에서.그러나 모든 속성 소스를 함께 지정해야 합니다. 즉, "재지정" 대신 "기본" 프로파일을 생성해야 합니다.
@Configuration
public class MyConfiguration
{
@Configuration
@Profile("default")
@PropertySource("classpath:defaults.properties")
static class Defaults
{ }
@Configuration
@Profile("override")
@PropertySource({"classpath:defaults.properties", "classpath:overrides.properties"})
static class Overrides
{
// nothing needed here if you are only overriding property values
}
@Autowired
private Environment environment;
@Bean
public Bean bean() {
...
// this.environment.getRequiredProperty("foo");
...
}
}
두 개의 파일을 정의할 것을 제안합니다. 두 번째 파일은 프로파일을 접미사로 지정한 선택 사항입니다.
@Configuration
@PropertySources({
@PropertySource("classpath:/myconfig.properties"),
@PropertySource(value = "classpath:/myconfig-${spring.profiles.active}.properties", ignoreResourceNotFound = true)
})
public class MyConfigurationFile {
@Value("${my.prop1}")
private String prop1;
@Value("${my.prop2}")
private String prop2;
}
할 수 있는 일:
<context:property-placeholder location="classpath:${spring.profiles.active}.properties" />
편집: 고급 기능이 필요한 경우 응용 프로그램을 시작할 때 속성 소스를 등록할 수 있습니다.
web.xml
<context-param>
<param-name>contextInitializerClasses</param-name>
<param-value>com.xxx.core.spring.properties.PropertySourcesApplicationContextInitializer</param-value>
</context-param>
생성하는 파일:
public class PropertySourcesApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
private static final Logger LOGGER = LoggerFactory.getLogger(PropertySourcesApplicationContextInitializer.class);
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
LOGGER.info("Adding some additional property sources");
String[] profiles = applicationContext.getEnvironment().getActiveProfiles()
// ... Add property sources according to selected spring profile
// (note there already are some property sources registered, system properties etc)
applicationContext.getEnvironment().getPropertySources().addLast(myPropertySource);
}
}
작업을 완료한 후에는 컨텍스트에 다음과 같이 추가하면 됩니다.
<context:property-placeholder/>
여러 프로필에 대한 당신의 질문에 대답할 수는 없지만, 그런 이니셜라이저에서 프로필을 활성화하고 프로필 활성화 중에 적절한 PropertySource 항목을 등록할 수 있습니다.
저는 당신이 에머슨에게 제안한 방법 외에는 다른 방법이 없습니다. 그것은 이 콩을 별도로 정의하는 것입니다.@Configuration
로 @Profile
주석:
@Configuration
@Profile("override")
@PropertySource("classpath:override.properties")
public class OverriddenConfig {
@Autowired
private Environment environment;
@Bean
public Bean bean() {
//if..
}
}
여러 프로파일을 지원해야 하는 경우 다음과 같은 작업을 수행할 수 있습니다.
@Configuration
public class Config {
@Configuration
@Profile("default")
@PropertySource("classpath:application.properties")
static class DefaultProperties {
}
@Configuration
@Profile("!default")
@PropertySource({"classpath:application.properties", "classpath:application-${spring.profiles.active}.properties"})
static class NonDefaultProperties {
}
}
이렇게 하면 각 프로필에 대해 정적 구성 클래스를 정의할 필요가 없습니다.데이비드 하크니스가 저를 올바른 방향으로 이끌어 주셔서 감사합니다.
참고: 이 답변은 속성 파일을 사용할 수 있는 대체 솔루션을 제공합니다.@PropertySource
중복 코드를 피하면서 각각 오버라이드가 있을 수 있는 여러 속성 파일을 작업하는 것이 너무 번거로워서 이 경로를 선택했습니다.
관련된 각 속성 집합에 대한 POJO 인터페이스를 만들어 이름과 유형을 정의합니다.
public interface DataSourceProperties
{
String driverClassName();
String url();
String user();
String password();
}
기본값을 반환하려면 구현합니다.
public class DefaultDataSourceProperties implements DataSourceProperties
{
public String driverClassName() { return "com.mysql.jdbc.Driver"; }
...
}
각 프로파일에 대한 하위 클래스(예: 개발, 생산)를 지정하고 기본값과 다른 값을 재정의합니다.이렇게 하려면 상호 배타적인 프로파일 집합이 필요하지만 "재지정" 대신 "기본값"을 쉽게 추가할 수 있습니다.
@Profile("production")
@Configuration
public class ProductionDataSourceProperties extends DefaultDataSourceProperties
{
// nothing to override as defaults are for production
}
@Profile("development")
@Configuration
public class DevelopmentDataSourceProperties extends DefaultDataSourceProperties
{
public String user() { return "dev"; }
public String password() { return "dev"; }
}
마지막으로 속성 구성을 필요한 다른 구성으로 자동 배선합니다.여기서 장점은 당신이 어떤 것도 반복하지 않는다는 것입니다.@Bean
생성 코드.
@Configuration
public class DataSourceConfig
{
@Autowired
private DataSourceProperties properties;
@Bean
public DataSource dataSource() {
BoneCPDataSource source = new BoneCPDataSource();
source.setJdbcUrl(properties.url());
...
return source;
}
}
서블릿 컨텍스트 이니셜라이저의 활성 프로필을 기반으로 속성 파일을 수동으로 구성하는 것에 대해 여전히 이 문제를 고수할지 확신할 수 없습니다.수동 구성을 하는 것이 유닛 테스트에 적합하지 않을 것이라고 생각했는데, 지금은 잘 모르겠습니다.저는 속성 접근자 목록보다 속성 파일을 읽는 것을 정말 좋아합니다.
여기에 언급된 솔루션은 모두 약간 어색하며, 하나의 프로필 사전 설정에서만 작동하며 더 많은/다른 프로필에서는 작동하지 않습니다.현재 Spring 팀은 이 기능의 도입을 거부하고 있습니다.하지만 제가 찾은 해결 방법은 다음과 같습니다.
package com.example;
public class MyPropertySourceFactory implements PropertySourceFactory, SpringApplicationRunListener {
public static final Logger logger = LoggerFactory.getLogger(MyPropertySourceFactory.class);
@NonNull private static String[] activeProfiles = new String[0];
// this constructor is used for PropertySourceFactory
public MyPropertySourceFactory() {
}
// this constructor is used for SpringApplicationRunListener
public MyPropertySourceFactory(SpringApplication app, String[] params) {
}
@Override
public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {
activeProfiles = environment.getActiveProfiles();
}
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource encodedResource) throws IOException {
logger.info("Loading: {} with profiles: {}", encodedResource.toString(), activeProfiles);
// here you know all profiles and have the source Resource with main
// properties, just try to load other resoures in the same path with different
// profile names and return them as a CompositePropertySource
}
}
그것을 작동시키기 위해서는 당신이 가지고 있어야 합니다.src/main/resources/META-INF/spring.factories
다음 내용을 포함합니다.
org.springframework.boot.SpringApplicationRunListener=com.example.MyPropertySourceFactory
이제 사용자 지정 속성 파일을 어딘가에 저장하고 로드할 수 있습니다.@PropertySources
:
@Configuration
@PropertySource(value = "classpath:lib.yml", factory = MyPropertySourceFactory.class)
public class PropertyLoader {
}
언급URL : https://stackoverflow.com/questions/12691812/can-propertysources-be-chosen-by-spring-profile
'programing' 카테고리의 다른 글
jQuery 자동 완성 및 ASP.NET (0) | 2023.09.01 |
---|---|
아약스 vs.웹 소켓 대웹 작업자 (0) | 2023.09.01 |
수평줄 가운데에 가운데 텍스트 추가 (0) | 2023.09.01 |
C 프로그래밍 언어에서 선언 시 2D 배열 초기화 (0) | 2023.09.01 |
다른 데이터베이스에 있는 하나의 데이터베이스에서 MySQL (0) | 2023.09.01 |