목표 : 스프링에서 Environment 설정을 할 수 있다.
이번에 진행하고자 하는 사항은 Environment 설정이다.
조금 더 구체적으로 Environment Abstraction이며, 그 위치는 다음과 같다.
Environment Interface
Environment Abstraction이라는 단어들로 알 수 있듯, 환경에 대한 추상화, 즉, Spring에서는 Environment Interface를 제공한다.
주로, Environment Interface는 profiles 나 properties 처럼, 프로그램의 환경 변수 그리고, Applcation의 프로필을 관리할 때 사용하게 된다.
다음 Environment Interface 문서를 보도록 하자.
모든 것들의 Super Interface는 PropertyResolver이며, acceptsProfiles나 getDefaultProfiles 등의 Method로 프로필 정보를 받아올 수 있다.
PropertyResolver 의 경우, getProperty 등으로, 환경 변수를 가져올 수 있다.
Resolver 라는 건 보통 변환기와 같은 의미로 사용된다.
PropertyResolver 역시, 환경변수를 사용하기 좋게 변환하는 역할을 한다고 보면 이해하기 쉽다.
Profile
Profile의 경우는 보통 서버환경에 따라 설정값을 달리 할 경우가 많다.
dev 환경에서는 Profile에 dev를 설정하고, Testbed, staging 서버에서는 stage 혹은 tb, 그리고 상용 서버에선 prod 로 설정하면서 Properties나 Datasource를 다르게 읽는 경우가 가장 자주 쓰이게 된다.
그럼 사용 예시를 한번 보도록 하자.
Datasource
Datasource Interface는 DB Connection 관리를 위해 사용한다.
jdbc에서 connection을 단순히 open을 하면, 하나의 Connection 만 연결된다.
그러나, 웹서버에서는 여러 요청에 따라 DB 자원을 사용해야하는데, 하나의 Connection으로는 무리가 따른다.
따라서, DataSource를 통해 Connection을 관리(Connection Pool)한다.
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.addScript("my-schema.sql")
.addScript("my-test-data.sql")
.build();
}
위와 같이 dataSource를 Bean으로 등록했다고 하자.
소스를 보듯, Embedded된 Datasource로, 개발환경에서 사용하는 경우일 것이다.
@Bean(destroyMethod="")
public DataSource dataSource() throws Exception {
Context ctx = new InitialContext();
return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
}
이제 application의 DataSource가 상용 서버의 JNDI 디렉토리에 등록되어 있다고 가정하고, 이를 상용 환경에 배포할 수 있는 방법을 고려해야 한다.
@Bean(destroyMethod="")
destroyMethod는 Bean이 Application Context에서 종료될 때, 호출되는 메서드이다.
Context ctx = new InitialContext();
Connection Pool에 접근하기 위해서는 JNDI 서비스를 사용해야 하며, JNDI는 서버에서 관리하고 있는 리소스에 대한 정보를 알고 있고, 특정 리소스를 찾아 사용할 수 있도록 객체를 반환한다.
ctx.lookup("java:comp/env/jdbc/datasource");
lookup은 DNS 서버에서 IP를 찾 듯, 리소스를 찾은 후 리소스를 사용할 수 있도록 객체를 반환해주는 메서드다.
찾고자 하는 리소스는 jdbc/datasource이며, WAS인 톰캣에서 리소스를 관리하는 가상의 디렉터리는 "java:comp/env"이라는 뜻이다.
JNDI : JNDI(Java Naming and Directory Interface)는 디렉터리 서비스에서 제공하는 데이터 및 객체를 발견하고 참고하기 위한 자바 API다. (분산환경에서 자원을 연결해주는 기능)
@Profile
그럼 이제, Profile을 통해 어떻게 접근할 수 있을지 보도록 하자.
@Configuration
@Profile("development")
public class StandaloneDataConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.addScript("classpath:com/bank/config/sql/schema.sql")
.addScript("classpath:com/bank/config/sql/test-data.sql")
.build();
}
}
@Configuration
@Profile("production")
public class JndiDataConfig {
@Bean(destroyMethod="")
public DataSource dataSource() throws Exception {
Context ctx = new InitialContext();
return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
}
}
위처럼 Annotation도 가능하지만, XML역시 가능하다.
<beans profile="development"
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="...">
<jdbc:embedded-database id="dataSource">
<jdbc:script location="classpath:com/bank/config/sql/schema.sql"/>
<jdbc:script location="classpath:com/bank/config/sql/test-data.sql"/>
</jdbc:embedded-database>
</beans>
<beans profile="production"
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="...">
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/datasource"/>
</beans>
그리고, 다음과 같이, 어떤 Profile을 Active 시킬지, 설정할 수 있다.
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setActiveProfiles("development");
ctx.register(SomeConfig.class, StandaloneDataConfig.class, JndiDataConfig.class);
ctx.refresh();
그러나 위처럼 하면, 소스를 수정해야 하므로, 보통 properties로 설정을 하며, 다음과 같이 설정하여 구동한다.
# properties 파일일 때 (application-prod.properties)
spring.profiles.active=prod
# yml 파일일 때 (application-prod.xml)
spring:
profiles:
active: prod
java -jar -Dspring.profiles.active=prod application.jar
Wrap up
아마 가장 처음에 Spring 프로젝트를 시작할 때 설정하는 부분일 것으로 보인다.
환경 설정은 아주 간단히 작성하였지만, 연동하는 point가 많을 수록 그 양이 상당해지고, 그에 따라 관리해야할 포인트도 많아진다. (특히, 배포 시에 Property 파일을 바꾸는 작업을 할 때는 주의해야한다.)
위와 같이, 단순히 환경설정하는 방법만 알고 진행하는 것보다 ,그에 대한 자세한 내용을 알아보았다.
'Framework > Spring' 카테고리의 다른 글
[Spring] Validation은 어떻게 확인할까? (0) | 2022.08.12 |
---|---|
[Spring] Resource는 어떻게 처리할까? (0) | 2022.08.11 |
[Spring] Classpath와 Component가 뭘까? (0) | 2022.08.02 |
[Spring] Annotation Configuration은 어떻게 할까? (0) | 2022.08.01 |
[Spring] Bean의 LifeCycle는 어떻게 될까? (0) | 2022.07.31 |