2015년 7월 20일 월요일

신입SW인력을 위한 실전 자바(Java) 스프링(Spring) 동영상과정 08_ 외부 파일을 이용한 Bean 객체 설정

이 게시물은
http://www.wiz.center/238

해당 링크를 청취하고 작성한 글입니다.

본인 이해도 확인을 위해서 작성한 것이니
스프링에 대해서 알고 있다면 쑥 훝어보고 끝내시고

좀 깊게 알고 싶다면 위의 링크부터 시작해서
총 30개 강의로 이루어진 스프링 과정을 청취하세요

1. Environment 객체를 이용해서 설정하는 방법
    사용할 파일(예를 들어 main) 에 다음 내용을 추가한다.

......
  ConfigurableApplicationContext ctx = new GenericXmlApplicationContext();
 ConfigurableEnvironment env = ctx.getEnvironment();
 MutablePropertySources propertySources = env.getPropertySources();

try{
        propertySources.addLast(new ResourcePropertySource("classpath:admin.properties"));
}catch{
...

Context 클래스로 객체 ctx를 만들고
    ctx.getEnvironment() 함수로 Environment 클래스의
    객체 env 를 생성후
    env.getPropertySources() 함수로 ProprtySources 클래스의
    객체 propertySources 를 생성 이후
    propertySources 객체에 리소스 위치를 알려주는 방법으로
    변수를 주입하는 방법이다. 이후 대응되는 클래스를
    Generic.... 으로 컨테이너와 빈을 만들어 쓰면 된다.

 프로젝트 생성시 적용하고 이후에는
     보기만 하면 된다.

-------------------------------
예제 1. Environment  객체 이용하기

 프로젝트 생성

작성1. applicationCTX.xml 을 resource 밑에 작성한다.



 




작성2. resource 밑에 admin.properties 라는 파일 하나를 생성하고
         아래와 같이 작성한다.

admin.id=admin
admin.pw=123456


작성3. src 밑에 AdminConnection.java 를 작성한다.

package com.javalec.ex;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;

public class AdminConnection implements EnvironmentAware, InitializingBean, DisposableBean {

 private Environment env;
 private String adminId;
 private String adminPw;
 
 @Override
 public void setEnvironment(Environment env) {
  System.out.println("setEnvironment()");
  setEnv(env);
 }
 
 public void setEnv(Environment env) {
  this.env = env;
 }
 
 public void setAdminId(String adminId) {
  this.adminId = adminId;
 }
 
 public void setAdminPw(String adminPw) {
  this.adminPw = adminPw;
 }
 
 public String getAdminId() {
  return adminId;
 }
 
 public String getAdminPw() {
  return adminPw;
 }
 
 @Override
 public void afterPropertiesSet() throws Exception {
  System.out.println("afterPropertiesSet()");
  setAdminId(env.getProperty("admin.id"));
  setAdminPw(env.getProperty("admin.pw"));
 }

 @Override
 public void destroy() throws Exception {
  System.out.println("destroy()");
 }

}


작성4. 테스트 결과를 확인할 MainClass.java 를 작성

package com.javalec.ex;

import java.io.IOException;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.io.support.ResourcePropertySource;


public class MainClass {

 public static void main(String[] args) {
  
  ConfigurableApplicationContext ctx = new GenericXmlApplicationContext();
  ConfigurableEnvironment env = ctx.getEnvironment();
  MutablePropertySources propertySources = env.getPropertySources();
  
  try {
   propertySources.addLast(new ResourcePropertySource("classpath:admin.properties"));
   
   System.out.println( env.getProperty("admin.id") );
   System.out.println( env.getProperty("admin.pw") );
  } catch (IOException e) {}
  
  GenericXmlApplicationContext gCtx = (GenericXmlApplicationContext)ctx;
  gCtx.load("applicationCTX.xml");
  gCtx.refresh();
  
  AdminConnection adminConnection = gCtx.getBean("adminConnection", AdminConnection.class);
  System.out.println("admin ID : " + adminConnection.getAdminId());
  System.out.println("amdin PW : " + adminConnection.getAdminPw());
  
  gCtx.close();
  ctx.close();
 }
}


결과 )  


결과를 보면 main 기준 getProperty 시점에서 내용을 가져오는게 보이고
   ctx 생성후
   setEnvironment() 가  bean 객체 초기화시 실행되는
     afterPropertiesSet() 보다 먼저 실행되는게 확인된다.
   이후 빈 객체에 변수 2개가 이식된게 확인되고
    이를 쓸수 있는 상태가 되었다.
Environment  클래스를 이용하는 경우 따로 변수명을 파일로 관리 할 수
   있긴 한데 좀 불편해 보이긴 하다.

----------------------------------------------------------

2. Environment  를 쓰지 않고 명시하는 방법
   2가지로 나뉘는데
    2-1) xml 에 해당 내용을 명시하는 방법
    2-2) java 에 어노테이션으로 명시하는 방법
-------------------------------
예제 2. Environment 를 쓰지 않고 명시하는 방법

작성1. resource 에 admin.properties 다음 내용을 작성한다.

admin.id=admin
admin.pw=123456


작성2. resource 에 sub_admin.properties 파일생성 및 작성


sub_admin.id=subadmin
sub_admin.pw=654321


작성3-1. resource 에 applicationCTX.xml 을 아래와 같이 작성한다.
        중간에
<context:property-placeholder location="classpath:admin.properties, classpath:sub_admin.properties" />
        이 부분에 프로퍼티 파일을 명시해 놓았다.


 
 
 
 
  
   ${admin.id}
  
  
   ${admin.pw}
  
  
   ${sub_admin.id}
  
  
   ${sub_admin.pw}
  
 



작성4. src 밑에 bean 생성할 AdminConnection.java 를 작성한다.

package com.javalec.ex;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class AdminConnection implements InitializingBean, DisposableBean {

 private String adminId;
 private String adminPw;
 private String sub_adminId;
 private String sub_adminPw;
 
 public void setAdminId(String adminId) {
  this.adminId = adminId;
 }
 
 public void setAdminPw(String adminPw) {
  this.adminPw = adminPw;
 }
 
 public void setSub_adminId(String sub_adminId) {
  this.sub_adminId = sub_adminId;
 }
 
 public void setSub_adminPw(String sub_adminPw) {
  this.sub_adminPw = sub_adminPw;
 }
 
 public String getAdminId() {
  return adminId;
 }
 
 public String getAdminPw() {
  return adminPw;
 }
 
 public String getSub_adminId() {
  return sub_adminId;
 }
 
 public String getSub_adminPw() {
  return sub_adminPw;
 }
 
 @Override
 public void afterPropertiesSet() throws Exception {
  System.out.println("afterPropertiesSet()");
 }

 @Override
 public void destroy() throws Exception {
  System.out.println("destroy()");
 }

}


작성5-1. src밑에 사용할 클래스 MainClass.java 를 작성한다.
       5-1에서는 applicationCTX.xml에서 사용하겠다고 명시해두었다.

package com.javalec.ex;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;

public class MainClass {

 public static void main(String[] args) {
  
  AbstractApplicationContext ctx = new GenericXmlApplicationContext("classpath:applicationCTX.xml");
  AdminConnection connection = ctx.getBean("adminConnection", AdminConnection.class);
  
  System.out.println("adminID : " + connection.getAdminId());
  System.out.println("adminPW : " + connection.getAdminPw());
  System.out.println("sub_adminID : " + connection.getSub_adminId());
  System.out.println("sub_adminPW : " + connection.getSub_adminPw());
  
  ctx.close();
 }
}


작성5-2. src밑에 사용할 클래스 MainClass.java 를 작성한다.
       5-1에서 AbstractApplicationContext 로 생성한 부분을
        아래처럼 다른 클래스로 구현했다.
       아직 언급하지 않은 ApplicationConfig.class 클래스를 bean 등록
       하도록 명시해놓았다. 

package com.javalec.ex;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;

public class MainClass {

 public static void main(String[] args) {
  
  AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ApplicationConfig.class);
  AdminConnection connection = ctx.getBean("adminConfig", AdminConnection.class);
  System.out.println("adminID : " + connection.getAdminId());
  System.out.println("adminPW : " + connection.getAdminPw());
  System.out.println("sub_adminID : " + connection.getSub_adminId());
  System.out.println("sub_adminPW : " + connection.getSub_adminPw());
  
  ctx.close();
 }
}


작성6-2. src 밑에  ApplicationConfig.java 를 작성한다.

package com.javalec.ex;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

@Configuration
public class ApplicationConfig {

 @Value("${admin.id}")
 private String adminId;
 @Value("${admin.pw}")
 private String adminPw;
 @Value("${sub_admin.id}")
 private String sub_adminId;
 @Value("${sub_admin.pw}")
 private String sub_adminPw;
 
 @Bean
 public static PropertySourcesPlaceholderConfigurer Properties() {
  PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
  
  Resource[] locations = new Resource[2];
  locations[0] = new ClassPathResource("admin.properties");
  locations[1] = new ClassPathResource("sub_admin.properties");
  configurer.setLocations(locations);
  
  return configurer;
 }
 
 @Bean
 public AdminConnection adminConfig() {
  AdminConnection adminConnection = new AdminConnection();
  adminConnection.setAdminId(adminId);
  adminConnection.setAdminPw(adminPw);
  adminConnection.setSub_adminId(sub_adminId);
  adminConnection.setSub_adminPw(sub_adminPw);
  return adminConnection;
 }
}


결과 )  xml 이나 java로 구현했느냐가 틀리고 호출하는 쪽에서는
     ctx 작성 클래스만 변경되어 있으면 java 나 xml 설정에서
     각각 따로 외부에서 작성된 파일에서 정보를 가져왔다.


----------------------------------------------------------


3. 프로파일 설정을 이용한 Bean 설정
    보통 사용자 환경(OS?, 개발 혹은 운영 등) 에 따라
     다른 환경 정보를 저장하기 위한 용도로 쓰인다.
    여기에도 xml 파일에서 설정하는 방법을 이용하거나
     java 파일에서 설정하는 방법을 이용하는 방법을 쓰거나
     둘중에 하나를 쓸 수 있다.

-------------------------------
예제 1. Environment  객체 이용하기

작성1. bean 객체에 해당되는 ServerInfo.java 파일 작성

package com.javalec.ex;

public class ServerInfo {

 private String ipNum;
 private String portNum;
 
 public String getIpNum() {
  return ipNum;
 }
 public void setIpNum(String ipNum) {
  this.ipNum = ipNum;
 }
 public String getPortNum() {
  return portNum;
 }
 public void setPortNum(String portNum) {
  this.portNum = portNum;
 }
 
}


작성2-1. 사용할 MainClass.java 를 작성
             여기서는 GenericXmlApplicationContext 를 이용해
             .xml 파일로 로드하도록 설정한다.
             여기서는 config 라는 문자열에 임의로 dev를 부여함

package com.javalec.ex;

import java.util.Scanner;

import org.springframework.context.support.GenericXmlApplicationContext;

public class MainClass {

 public static void main(String[] args) {
  
  String config = "dev";
                //String config = "run";
  
  scanner.close();
  
  GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
  ctx.getEnvironment().setActiveProfiles(config);
  ctx.load("applicationCTX_dev.xml", "applicationCTX_run.xml");
  
  ServerInfo info = ctx.getBean("serverInfo", ServerInfo.class);
  System.out.println("ip : " + info.getIpNum());
  System.out.println("port : " + info.getPortNum());
  ctx.close();
 }
}


작성2-2.   GenericXmlApplicationContext  이 아닌 
             AnnotationConfigApplicationContext 으로 ctx를 생성하고
             register 라는 함수로 xml 대신 class 를 할당한다.
package com.javalec.ex;

import java.util.Scanner;

import org.springframework.context.support.GenericXmlApplicationContext;

public class MainClass {

 public static void main(String[] args) {
  
  String config = "dev";
                //String config = "run";
  
  scanner.close();

  AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
  ctx.getEnvironment().setActiveProfiles(config);
  ctx.register(ApplicationConfigDev.class, ApplicationConfigRun.class);
  ctx.refresh();

  GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
  ctx.getEnvironment().setActiveProfiles(config);
  ctx.load("applicationCTX_dev.xml", "applicationCTX_run.xml");
  
  ServerInfo info = ctx.getBean("serverInfo", ServerInfo.class);
  System.out.println("ip : " + info.getIpNum());
  System.out.println("port : " + info.getPortNum());
  ctx.close();
 }
}



작성3-1. applicationCTX_dev.xml 을 resource 밑에 작성한다.
             여기서 profile 옵션을 dev 로 부여함.



 
  
  
 




작성3-2. ApplicationConfigDev.java 를 src 밑에 작성한다.

package com.javalec.ex;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

@Configuration
@Profile("dev")
public class ApplicationConfigDev {
 
 @Bean
 public ServerInfo serverInfo() {
  ServerInfo info = new ServerInfo();
  info.setIpNum("localhost");
  info.setPortNum("8181");
  return info;
 }
 
}


작성4-1. applicationCTX_run.xml 을 resource밑에 작성한다.
             여기서 profile 옵션을 run 로 부여함.



 
  
  
 




작성4-2. ApplicationConfigRun.class 를 src 밑에 작성한다.

package com.javalec.ex;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

@Configuration
@Profile("run")
public class ApplicationConfigRun {

 @Bean
 public ServerInfo serverInfo() {
  ServerInfo info = new ServerInfo();
  info.setIpNum("210.230.230.122");
  info.setPortNum("80");
  return info;
 }
 
}


결과 )  config = "dev" 일시



          config = "run" 일시

----------------------------------------------------------


댓글 없음:

댓글 쓰기