[외부 파일을 이용한 설정]
: Environment 객체 이용해서 외부의 설정 값을 가져와 이용
Environment의 사전적 정의 - 1. (주변의) 환경 2. (자연) 환경 3. 환경(컴퓨터, 사용자, 프로그램을 포함한 모든 것)
필요성
Environment 외부 설정------------->자바 클래스
(DB나 id/pass등 정보들)
- 요점은 외부의 설정 파일이 따로 있어서 수정 할 때 자바 클래스 수정없이 외부에서만 수정하면 된다.
순서
Context------------->Environment------------->PropertySources
1. 어플리케이션의 기초인 ConfigurableApplicationContext로 ctx 파일 생성
2. ctx.getEnvironment을 통해 얻은 객체를 ConfigurableEnvironment에서 생성한 Environment 객체 env에 담는다.
3. env.getPropertySources();로 프로퍼티소스를 얻어와서 MutablePropertySources에서 생성한 인스턴스에 넣는다.
getPropertySources();를 해주는 이유는 Environment 객체 안에는
각각의 정보를 갖고있는 PropertySources라는 객체가 있어서 다 구해오는 것.
요청만 하면 그게 id든 pass든 db든 알아서 가지고 온다고 한다.
(Environment - PropertySources(id,pass)
- PropertySources(db).... 이런식으로)
4. PropertySources에서 추가와 추출 가능 (추가 : addLast / 추출 : getProperty)
*
어차피 글만 보고 이해하기란 당연히 쉽지 않으니 이론이 이렇다 하는 것만 알아두고
예제를 하면서 다시 보면 쉬울 것이다.
ConfigurableApplicationContext
ConfigurableEnvironment
----------------------------------------------------------------------------------------------------------
admin.properties
1 2 | admin.id=admin admin.pw=12345 | cs |
*
아이디, 비밀번호 설정값
ctx_AdminExample.xml
1 | <bean id="adminConnection" class="com.yul.ex03_example.AdminConnection"/> | cs |
*
AdminConnection에 대한 객체 생성
MainClass.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | public class MainClass { public static void main(String[] args) { ConfigurableApplicationContext ctx = new GenericXmlApplicationContext(); ConfigurableEnvironment env = ctx.getEnvironment(); // ctx.getEnvironment(); MutablePropertySources propertySources = env.getPropertySources(); // env.getPropertySources(); try { propertySources.addLast(new ResourcePropertySource("classpath:admin.properties")); // 추가 : propertySources.addLast System.out.println(env.getProperty("admin.id")); // 추출 : env.getProperty System.out.println(env.getProperty("admin.pw")); } catch (IOException e) { e.getMessage(); } GenericXmlApplicationContext gctx = (GenericXmlApplicationContext)ctx; gctx.load("classpath:ctx_AdminExample.xml"); gctx.refresh(); // afterPropertiesSet() AdminConnection adminConnection = gctx.getBean("adminConnection", AdminConnection.class); System.out.println("admin Id = " + adminConnection.getAdminId()); System.out.println("admin pw = " + adminConnection.getAdminpw()); gctx.close(); ctx.close(); // destroy() } } | cs |
*
맨 위에 써놓은 순서를 되짚어 보고
MainClass와 AdminConnection.java를 번갈아보면서 해석해보자.
ConfigurableApplicationContext ctx = new GenericXmlApplicationContext();
1. 어플리케이션의 기초인 ConfigurableApplicationContext로 ctx 파일 생성
ConfigurableEnvironment env = ctx.getEnvironment();
2. ctx.getEnvironment을 통해 얻은 객체를 ConfigurableEnvironment에서 생성한 Environment 객체 env에 담는다.
MutablePropertySources propertySources = env.getPropertySources();
3. env.getPropertySources();로 프로퍼티소스를 얻어와서 MutablePropertySources에서 생성한 인스턴스에 넣는다.
getPropertySources();를 해주는 이유는 Environment 객체 안에는 각각의 정보를 갖고있는 PropertySources라는
객체가 있어서 다 구해오는 것. 요청만 하면 그게 id든 pass든 db든 알아서 가지고 온다고 한다.
propertySources.addLast(new ResourcePropertySource("classpath:admin.properties"));
System.out.println(env.getProperty("admin.id"));
System.out.println(env.getProperty("admin.pw"));
4. addLast을 통해 admin.properties를 추가했고 getProperty를 통해 그 안에 있는 admin.id와 admin.pw를 추출했다.
여기까지의 결과는
admin
12345
*
그 이후에는 그동안 배웠던 내용과 같다.
GenericXmlApplicationContext gctx = (GenericXmlApplicationContext)ctx;
gctx.load("classpath:ctx_AdminExample.xml");
gctx.refresh();
- Environment에 관한 내용이 담긴 ctx를 형변환하여 gctx 객체에 담고
xml파일을 로드하고, 초기화 작업을 한다.
AdminConnection adminConnection = gctx.getBean("adminConnection", AdminConnection.class);
System.out.println("admin Id = " + adminConnection.getAdminId());
System.out.println("admin pw = " + adminConnection.getAdminpw());
- ★이 부분이 중요할 것 같다.
xml파일에서 adminConnection을 getBean했는데
그동안 배운대로 라면 xml과 AdminConnection.java를 매핑하는 부분에서
private Environment env;
private String adminId;
private String adminpw;
이 필드를 property로 묶어줘야 맞는것 아닐까?
그런데 xml에는 Bean밖에 없고 코드에서는 자연스럽게 getAdminId, getAdminpw를 해주고 있다.
비밀은 앞선 4번 설명 코드에서 addLast를 통해 외부 파일의 프로퍼티 소스를 추가했고, 추출을 통해
env.getProperty("admin.id")와 env.getProperty("admin.pw") 이 값을 도출했기 때문이다.
이미 admin.properties 안에서 원하는 값을 뽑아냈다고 해야하나.
AdminConnection.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | public class AdminConnection implements EnvironmentAware, InitializingBean, DisposableBean { private Environment env; private String adminId; private String adminpw; @Override public void destroy() throws Exception { System.out.println("destroy() 실행"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("afterPropertiesSet() 실행"); setAdminId(env.getProperty("admin.id")); // Environment객체에 속한 메서드 - getProperty setAdminpw(env.getProperty("admin.pw")); } @Override public void setEnvironment(Environment env) { System.out.println("setEnvironment() 실행"); setEnv(env); } public Environment getEnv() { return env; } public void setEnv(Environment env) { this.env = env; } public String getAdminId() { return adminId; } public void setAdminId(String adminId) { this.adminId = adminId; } public String getAdminpw() { return adminpw; } public void setAdminpw(String adminpw) { this.adminpw = adminpw; } } | cs |
*
InitializingBean와 DisposableBean은 지난 시간 빈 생명주기에서 했으니 패스,
EnvironmentAware를 구현하면 setEnvironment가 오버라이딩되는데
이 의미는 빈이 생성되는 시점에 그 누구보다 가장 먼저 호출이 된다.
그리고 setEnv(env);를 써주는데
이 env가 바로 MainClass파일에 4번 설명 부분에서 추출한 값이다.
setEnvironment가 실행될 때는 빈이 생성되는 시점이므로
getProperty 하고 값을 뽑아낸 직후 getBean을 하니까 자연스럽게 값이 나오는 것이다.
env은 매개변수를 따라 올라가고 매개변수는 set으로 들어가고
this.env를 통해 필드값 env로 들어간다.
*
결과
admin
12345
setEnvironment() 실행
afterPropertiesSet() 실행
admin Id = admin
admin pw = 12345
destroy() 실행
'프로그래밍 > Spring' 카테고리의 다른 글
Spring / 외부 파일을 이용한 설정 - 프로퍼티 파일 직접 이용 (0) | 2018.04.08 |
---|---|
Spring / 스프링 빈의 범위(Bean Scope) (0) | 2018.04.07 |
Spring / 스프링 빈의 생명 주기(life cycle) (0) | 2018.04.07 |
Spring / 스프링 컨테이너의 생명주기(lifecycle) (0) | 2018.04.07 |
Spring / xml과 Java를 같이 사용하는 방법 (0) | 2018.04.07 |