스프링 프레임워크_DI

김예진·2023년 8월 27일

spring

목록 보기
6/13

DI(Dependency Injection, 의존성 주입) :

설정 파일이나 어노테이션을 통해 객체 간의 의존 관계를 설정하여 개발자가 직접 객체 간의 의존 관계를 생성할 필요가 없다.
-> 의존정 주입 = 직접적인 연결을 깨부수는 것 -> 결합도를 낮춤
-> 지난 과정에서(mybatis) DAO - service - Controller 순으로 연결되어 서로 객체 간의 직접 연결로 의존 관계가 높았다.

하지만 SPRING 프렘임워크에서는 객체 간의 직접연결을 깨부수고 어떠한 빈 공간(Spring container)에 객체를 저장해놓고 필요할 때 꺼내서 쓸 수 있도록 만들어 객체 간 결합도를 낮춘다.

-> 이번 시간에는 3개의 과정을 통해 객체 연결하는 방법을 알아보도록 하자

* 공통적인 부분 : Hello 객체 생성

1. Hello객체 생성 하여 직접 연결

2. properties파일에Hello객체를 저장한 후 HelloFactory를 통해 객체를 연결 시킨다.

  • properties 파일에 Hello 객체 파일 경로 저장
  • HelloFactory는 직접 구현
package com.kh.di;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

// hello.properties(부가정보, meta-data)의 내용을 읽어 Hello 객체를 생성하여 return
public class HelloFactory {

	private Hello hello;  
	private Properties properties;
	
	// 싱글톤 패턴 작성
	private static HelloFactory helloFactory;
	private HelloFactory() {}
	public synchronized static HelloFactory getInstance() {
		
		//synchronized : 동기화 하는 역할 (Factory(공장) 이 처리가 이루어지는 동안 나머지 것들의 접근을 막는 역할)
		if(helloFactory == null) {
			helloFactory = new HelloFactory();
		}
		return helloFactory;
	}
	
	// properties file을 추상화, 캡슐화한 java.util.properties 객체 생성
                       // congigResource는 properties 파일의 경로나 위치를 나타냄
	public void setConfigResource(String configResource) {
                                
		FileInputStream fis = null;
		try {         // FileInputStream 통해 congigResource에 지정된 경로의 properties파일을 연다.
			fis = new FileInputStream(configResource);
			properties = new Properties();
             // Properties 객체에 FileInputStream 통해 읽은 프롶티 파일을 로드(저장)한다.
             // 이 메소드는 파일에서 읽은 내용을 키=값 의 형태로 properties 객체에 저장  
                 -> 나중에 .getProperty(key)통해 값을 가져올 수 있음 
			properties.load(fis);      
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			if(fis!=null) {
				try {
					fis.close();
				} catch (IOException e) {
					
					e.printStackTrace();
				}
			}
		}
	}
	
	// name에 해당하는 객체 생성
	private void newInstanceHello(String name) {
                           // 키= 값 형태로 properties객체에 저장했기 때문에 .getProperty(name)통해 해당 값 가져올 수 잇음 
		String className = properties.getProperty(name).trim();
//		                                            trim : 앞 , 뒤 여백을 포함하고 잇는 것을 제거 
		System.out.println("hello.properties에서 추출한 className: " + className);
		try {
			Class cls = Class.forName(className);
			Object obj = cls.newInstance();
             // .newInstance() : 주어진 클래스의 기본 생성자 호출하여 새로운 객체 생성
              ex. "com.kh.di.hello" 클래스의 기본 생성자 호출 하여
                   "Hello" 클래스의 인스턴스가 생성됨
             
			if(obj instanceof Hello) { // 만든 클래스가 진짜 Hello 인지 확인
				this.hello = (Hello) obj;
			}
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}catch(Exception e) {
			e.printStackTrace();
		}
		
	}
	
	// Hello 객체 생성하는 new InstanceHello() 호출 및 Hello객체를 return
	public Hello getBean(String name) {
		this.newInstanceHello(name);
		return hello;
	}
	// getBean 메소드는 주어진 이름에 해당하는 클래스 생성하고 생성된 클래스의 인스턴스를 반환함으로써 
    // 특정 이름에 대응하는 빈(Bean)을 반환하는 역할
} 
  • 위에서 생성한 HelloFactory로 객체연결하여 실행

3. 스프링프레임워크 BeanFactory 사용하여 객체 연결

  • HelloFactory 대신 BeanFactory 사용
  • BeanFactory는 이미 만들어져 있기 때문에 우리가 따로 만들 필요가 없다.
  • BeanFactory : spring loC 컨테이너의 기본 인터페이스(빈의 생성, 의존성 주입, 초기화등의 기능을 함)
  • 2번째 방법에서는 Hello객체를 properties 파일에 저장했지만 이번엔 xml 파일에 저장해준다.

  • BeanFactory 사용하여 객체 연결

public class HelloTestApp3UsingSpring {

	public static void main(String[] args) {
		//1. BeanFactory 생성.. 주문서는 공장에서 미리 받아서 읽기
		// 주문서 만들기 : 빈(Bean)설정 문서
		System.out.println("1. BeanFactory 생성..");
		
		//이젠 HelloFactory 만들 필요 없이 만들어져 잇는 BeanFactory 이용
		BeanFactory factory = new XmlBeanFactory(new FileSystemResource("src/main/resources/config/hello.xml"));        
        //1. "src/main/resources/config/hello.xml" 경로에 있는 Bean 설정 문서인 hello.xml을 읽어오기 위해 FileSystemResource를 생성
       //2.  FileSystemResource 객체를 XmlBeanFactory 생성자에 전달하여 설정 파일을 로드
       //3. XmlBeanFactory는 설정 파일을 읽어와서 빈(Bean) 객체 생성하여 변수 factory에 저장
		
  
		// 2. getBean()으로 빈을 받아와서 printMessage() 호출
		System.out.println("2.getBean() 클라이언트 호출...");
		Hello hello = (Hello)factory.getBean("hello");   //"hello" 는 hello.xml에서 설정한 id
		hello.printMessage();
	}

}

profile
코린이

0개의 댓글