Spring Boot application.properties를 프로그래밍 방식으로 덮어쓰려면 어떻게 해야 합니까?
외부 구성 웹 서비스에서 가져온 jdbc 속성 파일을 가지고 있습니다.봄 부팅 시 mysql 소품을 설정하려면 이러한 파일을 application.properties에 추가하는 것이 쉽습니다.
spring.datasource.url=jdbc:mysql://localhost/mydb
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
내 앱에 있는 프로그램들을 덮어쓰려면 어떻게 해야 하나요?
스프링 배치 소품도 마찬가지입니다.
database.driver=com.mysql.jdbc.Driver
database.url=jdbc:mysql://localhost/mydv
database.username=root
database.password=root
ApplicationEnvironmentPrepared 이벤트에 반응하는 라이프사이클 리스너에 속성 소스를 추가할 수 있습니다.
다음과 같은 것들이 있습니다.
public class DatabasePropertiesListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
ConfigurableEnvironment environment = event.getEnvironment();
Properties props = new Properties();
props.put("spring.datasource.url", "<my value>");
environment.getPropertySources().addFirst(new PropertiesPropertySource("myProps", props));
}
}
그런 다음 src/main/resources/META-INF/spring.factories에 클래스를 등록합니다.
org.springframework.context.ApplicationListener=my.package.DatabasePropertiesListener
이 방법은 효과가 있었습니다만, 아직 애플리케이션 기동 단계이기 때문에, 현시점에서는 할 수 있는 일이 한정되어 있기 때문에, 다른 스프링 콩 등에 의존하지 않고 필요한 가치를 얻을 수 있는 방법을 찾아야 합니다.
요건에 대한 답을 찾기 시작했을 때 참조용으로 이 스레드에 다른 옵션을 제공하기 위해 검색 목록에서 상위 항목이 되었지만 사용 사례에 대해서는 다루지 않았습니다.
기동시에 spring boot 속성을 프로그래밍 방식으로 설정하려고 했습니다만, spring이 서포트하고 있는 다른 XML/Config 파일을 조작할 필요는 없습니다.
가장 쉬운 방법은 Spring Application 정의 시 속성을 설정하는 것입니다.다음 기본 예에서는 Tomcat 포트를 9999로 설정합니다.
@SpringBootApplication
public class Demo40Application{
public static void main(String[] args){
SpringApplication application = new SpringApplication(Demo40Application.class);
Properties properties = new Properties();
properties.put("server.port", 9999);
application.setDefaultProperties(properties);
application.run(args);
}
}
스프링 부트 1.3 Environment Post Processor를 이 목적으로 사용할 수 있습니다.서브클래스를 생성하여 META-INF/spring.factories에 등록합니다.좋은 예는 다음과 같습니다.
Spring Boot 2.0.X 에서는 커스텀 Application Context Initializer 와 Context Configuration 주석의 조합을 사용하여 (유닛테스트 등) 개개의 속성을 동적으로 덮어쓸 수 있습니다.
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.PortTest.RandomPortInitailizer;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.support.TestPropertySourceUtils;
import org.springframework.util.SocketUtils;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(initializers = RandomPortInitializer.class)
public class PortTest {
@Autowired
private SomeService service;
@Test
public void testName() throws Exception {
System.out.println(this.service);
assertThat(this.service.toString()).containsOnlyDigits();
}
@Configuration
static class MyConfig {
@Bean
public SomeService someService(@Value("${my.random.port}") int port) {
return new SomeService(port);
}
}
static class SomeService {
private final int port;
public SomeService(int port) {
this.port = port;
}
@Override
public String toString() {
return String.valueOf(this.port);
}
}
public static class RandomPortInitializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
int randomPort = SocketUtils.findAvailableTcpPort();
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(applicationContext,
"my.random.port=" + randomPort);
}
}
}
이 해야 하는 : 이므로 spring-test 5.2.5를 사용할 수 .@DynamicPropertySource
:
@DynamicPropertySource
static void setDynamicProperties(DynamicPropertyRegistry registry) {
registry.add("some.property", () -> some.way().of(supplying).a(value) );
}
자산을 공급하는 다른 모든 방법보다 우선합니다.단, 메서드는 스태틱해야 합니다.
이것은 매우 단순할 수 있습니다.
@SpringBootApplication
public class SampleApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(SampleApplication.class)
.properties(props())
.build()
.run(args);
}
private static Properties props() {
Properties properties = new Properties();
properties.setProperty("MY_VAR", "IT WORKS");
return properties;
}
}
application.yml
test:
prop: ${MY_VAR:default_value}
스프링 부트 애플리케이션을 실행하고 있는 경우는, 기동시에 속성을 설정할 수 있습니다.
가장 쉬운 방법은 앱을 시작하기도 전에 속성을 설정하는 것입니다.
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(Application.class);
ConfigurableEnvironment env = new ConfigurableEnvironment();
env.setActiveProfiles("whatever");
Properties properties = new Properties();
properties.put("server.port", 9999);
env.getPropertySources()
.addFirst(new PropertiesPropertySource("initProps", properties));
application.setEnvironment(env);
application.run(args);
}
}
구성에서 이 방법을 사용하여 기본 속성을 설정할 수 있습니다.
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class)
.properties("propertyKey=propertyValue");
}
이렇게 하면 필요에 따라 application.properties를 프로그램적으로 덮어쓸 수 있습니다.
public static void main(String[] args) {
SpringApplication app = new SpringApplication(Restdemo1Application.class);
app.setAdditionalProfiles("dev");
// overrides "application.properties" with "application-dev.properties"
app.run(args);
}
응용 프로그램 클래스에 문자열 추가
@SpringBootApplication
public class Application {
public static void main(String[] args) {
System.setProperty("spring.config.location",
"file:///D:/SpringProjects/SpringBootApp/application.properties");
SpringApplication.run(Application.class, args);
}
}
META-INF 폴더 아래에 spring > batch > override > data-source-context.xml 폴더와 파일을 만듭니다.xml 파일에는 원하는 파라미터를 다음과 같이 덮어씁니다.
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${loader.jdbc.driver}" />
<property name="url" value="${loader.jdbc.url}" />
<property name="username" value="${loader.jdbc.username}" />
<property name="password" value="${loader.jdbc.password}" />
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
또는 xml 파일에서 이와 같은 jndi를 사용하여 catalina.properties와 같은 외부 설정 파일에 액세스합니다.
<jee:jndi-lookup id="dataSource"
jndi-name="java:comp/env/jdbc/loader-batch-dataSource" lookup-on-startup="true"
resource-ref="true" cache="true" />
언급URL : https://stackoverflow.com/questions/29072628/how-can-i-override-spring-boot-application-properties-programmatically
'programing' 카테고리의 다른 글
Larabel 및 Wordpress가 동일한 서버/도메인 상에 있음 (0) | 2023.04.01 |
---|---|
toString()을 구현할 때 reflection을 사용하는 것이 의미가 있습니까? (0) | 2023.04.01 |
Spring MVC 컨트롤러 메서드에서 GET HTTP 요청의 파라미터 값을 취득하려면 어떻게 해야 합니까? (0) | 2023.04.01 |
AngularJs가 반복 실행을 너무 많이 브로드캐스트합니다. (0) | 2023.04.01 |
오류: $digest가 이미 진행 중입니다. (0) | 2023.04.01 |