Salted Caramel

[수업 85일차] 21.12.10 / Spring 1 / 01_NonSpring/ 02_DI 본문

coding/[2021.08.02~2022.01.24] 수업복습

[수업 85일차] 21.12.10 / Spring 1 / 01_NonSpring/ 02_DI

꽃무늬라떼 2021. 12. 13. 04:31

* 추상클래스

* 비지니스 로직

 


01_NonSpring

com.sist.nonspring

package com.sist.nonspring;

public class AA {

	public void printMsg() {
		
		System.out.println("Hello");
		
	}
}
package com.sist.nonspring;

public class BB {

	public void printMsg() {
		
		System.out.println("안녕하세요!!!");
		
	}
}
package com.sist.nonspring;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Handles requests for the application home page.
 */
@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
}
package com.sist.nonspring;

public class Main {

	public static void main(String[] args) {
		
		// AA aa = new AA();
		
		// aa.printMsg();
		
		BB bb = new BB();  //main
		
		bb.printMsg();
		 
	}

}

01_NonSpring

com.sist.nonspring02

package com.sist.nonspring02;

public interface Calculator {

	int sum(int firstNum, int secondNum);   // 추상메서드
	
}
package com.sist.nonspring02;

public class CalDiv implements Calculator {

	@Override
	public int sum(int firstNum, int secondNum) {
		
		return secondNum != 0 ? (firstNum / secondNum) : 0;
		
	}

}
package com.sist.nonspring02;

public class CalMul implements Calculator {

	@Override
	public int sum(int firstNum, int secondNum) {
		
		return firstNum * secondNum;
		
	}

}
package com.sist.nonspring02;

public class CalSub implements Calculator {

	@Override
	public int sum(int firstNum, int secondNum) {
		
		return firstNum - secondNum;
	}

}
package com.sist.nonspring02;

public class CalSum implements Calculator {

	@Override
	public int sum(int firstNum, int secondNum) {
		
		return firstNum + secondNum;
		
	}

}
package com.sist.nonspring02;

public class Main {

	public static void main(String[] args) {
		
		// Calculator calculator = new CalSum();
		
		// System.out.println(calculator.sum(25, 12));
		
		MyCalculator calculator;
		
		calculator = new MyCalculator(10, 5, new CalDiv());
		
		calculator.result();

	}

}
package com.sist.nonspring02;

public class MyCalculator {

	private int firstNum;
	private int secondNum;
	private Calculator calculator;
	
	public MyCalculator() {  }   //기본 생성자 
	
	public MyCalculator(int firstNum, int secondNum,  
			Calculator calculator) { //인자 생성자 
		this.firstNum = firstNum;
		this.secondNum = secondNum;
		this.calculator = calculator;
	}

	public int getFirstNum() {
		return firstNum;
	}

	public void setFirstNum(int firstNum) {
		this.firstNum = firstNum;
	}

	public int getSecondNum() {
		return secondNum;
	}

	public void setSecondNum(int secondNum) {
		this.secondNum = secondNum;
	}

	public Calculator getCalculator() {
		return calculator;
	}

	public void setCalculator(Calculator calculator) {
		this.calculator = calculator;
	}
	
	// 비지니스 로직
	public void result() {
		int value = calculator.sum(firstNum, secondNum);
		System.out.println("result >>> " + value);
	}
}

01_NonSpring

com.sist.nonspring03

package com.sist.nonspring03;

public interface DAO {

	void add();      // 추상메서드
	
}
package com.sist.nonspring03;

public class Main {

	public static void main(String[] args) {
		
		// 기존에 Java, JSP에서 사용하던 방식
		MySqlDAO sqlDAO = new MySqlDAO();
		sqlDAO.add();
		
		OracleDAO oracleDAO = new OracleDAO();
		oracleDAO.add();
		
		System.out.println("===========================");
		
		// 1. 인자생성자를 이용하여 주입하는 방법
		ServiceImpl impl1 = new ServiceImpl(new MySqlDAO());
		impl1.biz();
		
		// 2. setter() 메서드를 이용하여 주입하는 방법
		ServiceImpl impl2 = new ServiceImpl();
		impl2.setDao(new OracleDAO());
		impl2.biz();
		

	}

}
package com.sist.nonspring03;

public class MySqlDAO implements DAO {

	@Override
	public void add() {
		
		System.out.println("MySqlDAO 입니다.....");
		
	}

}
package com.sist.nonspring03;

public class OracleDAO implements DAO {

	@Override
	public void add() {
		
		System.out.println("OracleDAO 입니다.....");
		
	}

}
package com.sist.nonspring03;

public class ServiceImpl {

	private DAO dao;
	
	public ServiceImpl() {  }
	
	public ServiceImpl(DAO dao) {
		this.dao = dao;
	}

	public DAO getDao() {
		return dao;
	}

	public void setDao(DAO dao) {
		this.dao = dao;
	}
	
	// 비지니스 로직
	public void biz() {
		dao.add();
	}
	
}

 

 


02_DI

* 스프링 개요
  - 선수학습 : java, jsp(servlet), 스크립트언어(html. javascript, css, jquery)
  - 개념 : 자바 언어를 기반으로 한 애플리케이션을 제작할 때 효율적으로 빠르게 개발할 수 
                   있도록 하는 애플리케이션 프레임워크(프로그래밍 툴).
                   
* 스프링 프레임워크란?
  - 스프링은 엔터프라이즈(기업용) 애플리케이션에서 필요로 하는 여러가지 기능들을 제공하는 프레임워크.
  
  - Java EE가 제공하는 기능들을 스프링에서도 지원하고 있기 때문에 국내에서 가장 인기 있는 프레임워크로
        자리를 잡았음.
        
  - 스프링은 Java EE에서 제공하는 기능 외에 DI나 AOP와 같은 기능들을 추가적으로 제공함.
  
  - Java EE에서 MVC-2 모델 방식도 새로운 애플리케이션을 개발할 때마다 일일이 처음부터
        다시 개발해야 하는 단점이 있음. 모든 애플리케이션에서 공통적인 기능들을 처음부터 다시
        개발해야 한다는 것은 상당히 비효율적임.
        
  - 이보다 더 좋은 방법은 없는 것일까??   있다... 바로 스프링이다.
        애플리케이션 개발 시에 일반적인 웹 애플리케이션에서 많이 사용하는 기능들은 미리 만들어서 제공을 하고,
        그 외의 필요한 부분만 추가 및 수정하는 방식을 이용하면 됨. 이렇게 하면 훨씬 효율적일 뿐만 아니라
        일정한 형식에 따라서 개발을 진행하므로 표준화가 이루어져 생산성도 높일 수 있음.
        
  - 애플리케이션은 규모가 커질수록 각각의 기능들을 개발자가 따로 개발하는 것보다는 표준화된 방법으로
        개발하는 것이 상당히 유리함.
        
  - 그렇다면 프레임워크(framework)란?
        프레임워크(framework)의 사전적 의미는 "어떤 것을 구성하는 구조 또는 뼈대" 임.
        소프트웨어적 의미로는 "기능을 미리 클래스나 인터페이스 등으로 만들어 제공하는 반제품"
        정도로 해석을 할 수 있음. 즉, 어느 정도는 완성된 상태로 제공되는 기능을 말함.
        
        
        
* 스프링 프레임워크의 특징.
  - 스프링은 경량의 프레임워크.
    * 자바의 객체를 담고 있는 컨테이너(IoC 컨테이너).
    * 객체의 생성, 관리, 소멸과 같은 생명 주기를 관리함.
  - 스프링은 유지보수가 용이함.
  - 스프링은 개발 기간을 효율적으로 단축할 수 있음.
  

* DI(Dependency Injection : 의존성 주입)
  - DI는 스프링 핵심 개념 중 하나임.
  
  - 기존에는 어떤 한 클래스가 다른 클래스의 기능(메서드)을 사용하려면 당연히 개발자가 코드에서 직접적으로
        사용할 클래스의 생성자를 호출해서 사용을 하였음(new 키워드를 이용).
        따라서 사용할 클래스와 사용될 클래스의 관계는 개발자에 의해 직접 코드에서 부여가 되었음.
    (의존도가 높음 - 강한 결합)
    
  - 스프링에서는 객체 사이의 의존 관계를 객체 자신이 아닌 외부(스프링 컨테이너)에서 수행하는 개념임.
        즉, 이런 연관 관계를 개발자가 직접 코딩을 통해서 부여하는 것이 아니라 스프링 컨테이너가 연관 관계를
        직접 규정하는 것을 말함. 그러면 코드에서 직접적인 연관 관계가 발생하지 않으므로 각각의 클래스들의
        변경이 자유로워짐(약한 결합).
        따라서 스프링 프레임워크에서는 각 클래스들의 연관 관계를 클래스들 간의 사이에서 맺어지는 것이 아니라
        스프링 프레임워크에서 설정을 통해 맺어줌으로써 클래스들끼리 연관 관계를 맺지 않도록 구현을 해 놓았음.
        
  - 스프링 프레임워크에서 의존 관계 설정은 설정 파일(bean.xml)이나 애노테이션을 이용하여 설정을 함.
  
  - 스프링에서 클래스(빈 : bean)를 담는 그릇을 컨테이너라고 함.
        스프링 기반 애플리케이션에서는 스프링 컨테이너에서 객체가 태어나고, 자라고 소멸을 함.
        스프링 컨테이너는 객체를 생성하고, 서로 엮어 주고, 이들의 전체 생명 주기를 관리함.
        스프링 컨테이너는 스프링 프레임워크 핵심부에 위치함. 스프링 컨테이너는 종속 객체 주입을 이용해서
        애플리케이션을 구성하는 컴포넌트를 관리하며, 협력 컴포넌트 간 연관 관계의 형성도 스프링 컨테이너에서
        이루어짐.
        

* DI(의존성 주입) 하는 방법 - 2가지
  - setter(설정 메서드)를 이용한 주입.
  - constructor(인자 생성자)를 이용한 주입.
  
  
* 의존 관계를 설정하는 방법
  - XML 파일을 이용하여 의존 관계 설정.
  - Java 코드를 이용하여 의존 관계 설정. - 애노테이션을 이용.
  - XML 과 Java 를 혼용해서 의존 관계 설정.
package com.sist.di01;

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

/*
 * - 스프링은 객체를 생성하고 각각의 객체를 연결해 주는 조립기 역할을 함.
 * - 여기에 있는 GenericXmlApplicationContext 객체가 조립기 기능을 구현한 클래스임.
 * - 조립기에서 생성할 객체가 무엇이고, 각 객체를 어떻게 연결하는지에 대한 정보는 xml 파일에 설정이 되어 있음.
 * - GenericXmlApplicationContext 객체는 이 xml 파일에 정의된 설정 정보를 읽어 와서 객체를 생성하고,
 *   각각의 객체를 연결한 뒤에 내부적으로 보관을 함.
 * - xml을 이용한 스프링 설정을 하다 보면 컨테이너가 생성할 객체를 지정하기 위해 <bean> 태그를 사용하게 됨.
 * - 스프링 컨테이너가 생성해서 보관하는 객체를 스프링 빈(spring bean) 객체라고 부르며, 일반적으로 
 *   자바 객체와 동일함.
 * - 스프링 컨테이너는 생성한 빈 객체를 <이름, 빈 객체> 이렇게 쌍으로 보관을 함.
 * - 스프링 컨테이너가 보관하고 있는 객체를 사용하고 싶은 경우 빈 객체와 연결되어 있는 이름을 이용해서 객체를 참조하게 됨. 
 */

/*
 * 스프링 컨테이너의 종류
 * - BeanFactory : 단순히 스프링 컨테이너에서 객체를 생성하고 DI만 처리해 주는 기능만을 제공해 주는 객체.
 *                 하지만 스프링을 사용하는 이유는 단순히  DI만 사용하기 위함이 아닌 스프링을 사용하는
 *                 다양한 부가 기능(트랜잭션 처리, 자바 코드 기반의 스프링 설정, 애노테이션을 이용한
 *                 빈 설정, 스프링을 이용한 웹 개발 등등) 때문인데 이러한 부가 기능을 사용하기 위해서는
 *                 ApplicationContext 객체를 주로 사용하게 됨.
 * - AbstractApplicationContext : 컨테이너 종료(close)와 같은 기능을 제공해 주는 객체.
 * - GenericXmlApplicationContext : AbstractApplicationContext 객체를 상속을 받아서 만들어진
 *                                  클래스로서 xml 파일에서 스프링 빈 설정 정보를 읽어 오는 역할을 함.
 *                                  GenericXmlApplicationContext 객체를 생성할 때 파라미터 
 *                                  값으로 "classpath:getsum.xml" 을 전달했는데 이는 클래스 
 *                                  패스에 위치한 xml 파일을 설정 파일로 사용한다는 의미임.
 * - GenericXmlApplicationContext 객체는 전달 받은 xml 파일에서 설정 정보를 읽어 와서 스프링 빈 객체를
 *   생성하고 프로퍼티 값을 설정을 해 줌. 이렇게 생성된 빈 객체는 getBean() 이라는 메서드를 사용해서 구현을
 *   할 수 있음. getBean() 메서드의 첫번째 파라미터는 구현하고자 하는 스프링 빈 객체의 고유한 id 이름이며,
 *   두번째 파라미터는 그 객체의 클래스 타입을 의미함.                               
 */

public class Main {

	public static void main(String[] args) {
		
		// AbstractApplicationContext 객체가 DI 작업을 해 주는 스프링 컨테이너.
		// xml 파일을 이용하여 메모리로 해당 xml 파일이 로딩이 됨.
		AbstractApplicationContext ctx = 
				new GenericXmlApplicationContext("classpath:getsum.xml");
		
		// MyGetSum mysum = (MyGetSum)ctx.getBean("mySum");
		
		MyGetSum mysum = ctx.getBean("mySum", MyGetSum.class);
		
		mysum.sum();
		
		// 사용을 한 자원은 반납을 해야 함.
		ctx.close();

	}

}

 

<!-- 
	    <bean>
	       - id 속성 : "빈의 고유한 이름(중복불가), 클래스에서 작성한 변수(참조변수) 이름"
	       - class 속성 : "스프링 컨테이너에서 객체를 생성할 클래스의 위치(패키지명.클래스명)"
	    </bean>
	
	 -->
	
	<!-- 
	     com.sist.di02 패키지에 있는 ExamDaoImpl 클래스를
	     "daoImpl" 아리는 id를 지정하여 객체(bean)를 생성한다는 의미.
	     ExamDaoImpl daoImpl = new ExamDaoImpl();
	 -->

 

 


02_DI 

com.sist.di01

package com.sist.di01;

public class GetSum {

	private int su1;
	private int su2;
	
	public int getSu1() {
		return su1;
	}
	public void setSu1(int su1) {
		this.su1 = su1;
	}
	public int getSu2() {
		return su2;
	}
	public void setSu2(int su2) {
		this.su2 = su2;
	}
	
	// 핵심적인 기능(비지니스 로직)
	public void hap(int su1, int su2) {
		System.out.println("더하기 >>> " + (su1 + su2));
	}
	
}
package com.sist.di01;

public class MyGetSum {
	
	private int su1;
	private int su2;
	private GetSum getSum;
	
	public int getSu1() {
		return su1;
	}
	public void setSu1(int su1) {
		this.su1 = su1;
	}
	public int getSu2() {
		return su2;
	}
	public void setSu2(int su2) {
		this.su2 = su2;
	}
	public GetSum getGetSum() {
		return getSum;
	}
	public void setGetSum(GetSum getSum) {
		this.getSum = getSum;
	}
	
	// 핵심 기능
	public void sum() {
		this.getSum.hap(su1, su2);
	}

}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<!-- 외부에서 선언하는 방법 
  GetSum getsum = new GetSum(); -->
	<bean id="getsum" class="com.sist.di01.GetSum"/>  
	<bean id="mySum" class="com.sist.di01.MyGetSum">
	<property name="su1" value="200"/>
	<property name="su2" value="200"/>
	<property name="getSum">	
		<ref bean="getsum"/>
	</property>
	</bean>
</beans>

property - setter 메서드로 주입 su1(name)이라는 멤버변수에 200이라는 값(value)을 할당

ref bean을 참조하는데 아이디가 getsum이라는 변수를 참조함.

 

스프링 컨테이너 객체를 선언해준는데 일단은 xml파일을 이용하여 메모리로 해당  xml파일이 로딩이 .아이디에 해당하는 빈을 가져와서 받아오기.  

 

🍎🍎🍎🍎🍎🍎

package com.sist.di01;

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

/*
 * - 스프링은 객체를 생성하고 각각의 객체를 연결해 주는 조립기 역할을 함.
 * - 여기에 있는 GenericXmlApplicationContext 객체가 조립기 기능을 구현한 클래스임.
 * - 조립기에서 생성할 객체가 무엇이고, 각 객체를 어떻게 연결하는지에 대한 정보는 xml 파일에 설정이 되어 있음.
 * - GenericXmlApplicationContext 객체는 이 xml 파일에 정의된 설정 정보를 읽어 와서 객체를 생성하고,
 *   각각의 객체를 연결한 뒤에 내부적으로 보관을 함.
 * - xml을 이용한 스프링 설정을 하다 보면 컨테이너가 생성할 객체를 지정하기 위해 <bean> 태그를 사용하게 됨.
 * - 스프링 컨테이너가 생성해서 보관하는 객체를 스프링 빈(spring bean) 객체라고 부르며, 일반적으로 
 *   자바 객체와 동일함.
 * - 스프링 컨테이너는 생성한 빈 객체를 <이름, 빈 객체> 이렇게 쌍으로 보관을 함.
 * - 스프링 컨테이너가 보관하고 있는 객체를 사용하고 싶은 경우 빈 객체와 연결되어 있는 이름을 이용해서 객체를 참조하게 됨. 
 */

/*
 * 스프링 컨테이너의 종류
 * - BeanFactory : 단순히 스프링 컨테이너에서 객체를 생성하고 DI만 처리해 주는 기능만을 제공해 주는 객체.
 *                 하지만 스프링을 사용하는 이유는 단순히  DI만 사용하기 위함이 아닌 스프링을 사용하는
 *                 다양한 부가 기능(트랜잭션 처리, 자바 코드 기반의 스프링 설정, 애노테이션을 이용한
 *                 빈 설정, 스프링을 이용한 웹 개발 등등) 때문인데 이러한 부가 기능을 사용하기 위해서는
 *                 ApplicationContext 객체를 주로 사용하게 됨.
 * - AbstractApplicationContext : 컨테이너 종료(close)와 같은 기능을 제공해 주는 객체.
 * - GenericXmlApplicationContext : AbstractApplicationContext 객체를 상속을 받아서 만들어진
 *                                  클래스로서 xml 파일에서 스프링 빈 설정 정보를 읽어 오는 역할을 함.
 *                                  GenericXmlApplicationContext 객체를 생성할 때 파라미터 
 *                                  값으로 "classpath:getsum.xml" 을 전달했는데 이는 클래스 
 *                                  패스에 위치한 xml 파일을 설정 파일로 사용한다는 의미임.
 * - GenericXmlApplicationContext 객체는 전달 받은 xml 파일에서 설정 정보를 읽어 와서 스프링 빈 객체를
 *   생성하고 프로퍼티 값을 설정을 해 줌. 이렇게 생성된 빈 객체는 getBean() 이라는 메서드를 사용해서 구현을
 *   할 수 있음. getBean() 메서드의 첫번째 파라미터는 구현하고자 하는 스프링 빈 객체의 고유한 id 이름이며,
 *   두번째 파라미터는 그 객체의 클래스 타입을 의미함.                               
 */

public class Main {

	public static void main(String[] args) {
		
		// AbstractApplicationContext 객체가 DI 작업을 해 주는 스프링 컨테이너.
		// xml 파일을 이용하여 메모리로 해당 xml 파일이 로딩이 됨.
		AbstractApplicationContext ctx = 
				new GenericXmlApplicationContext("classpath:getsum.xml");
		
		// MyGetSum mysum = (MyGetSum)ctx.getBean("mySum");
		
		MyGetSum mysum = ctx.getBean("mySum", MyGetSum.class);
		
		mysum.sum();
		
		// 사용을 한 자원은 반납을 해야 함.
		ctx.close();

	}

}

사용하고 나서 반납을 해줘서 메모리를 효율적으로 관리를 해줘야 한다.

 

둘 중에 하나로 사용하면 됨

MyGetSum mysum = (MyGetSum)ctx.getBean("mySum");

 

MyGetSum mysum = ctx.getBean("mySum", MyGetSum.class);

==> 객체의 클래스 타입을 선언해서 형변환을 안하는 방법



02_DI 

com.sist.di02

 

간단하게 속성 없이 출력 

스프링컨피규어 파일에서 exam 객체만 생성해주고 printmsg만 출력해주면 됨 

new 라는 키워드를 쓰는게 아니라 spring contener에서 bean 가져올때 고유의 아이디값으로 가져오는데 이때 printmsg 호출해서 사용한다.

 

 

package com.sist.di02;

public interface ExamDAO {

	void printMsg();      // 추상 메서드
	
}

 

상속을 해서 정의 (implements)

package com.sist.di02;

public class ExamDaoImpl implements ExamDAO {

	@Override
	public void printMsg() {
		
		System.out.println("ExamDaoImpl 클래스의 printMsg() 메서드!!!");
		
	}
	

}
package com.sist.di03;

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

public class Main {

	public static void main(String[] args) {
		
		AbstractApplicationContext ctx = 
				new GenericXmlApplicationContext("classpath:mydao.xml");
		
		ServiceImpl service = (ServiceImpl)ctx.getBean("service");
		
		service.biz();
		
		ctx.close();

	}

}

examdao.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<!-- 
	    <bean>
	       - id 속성 : "빈의 고유한 이름(중복불가), 클래스에서 작성한 변수(참조변수) 이름"
	       - class 속성 : "스프링 컨테이너에서 객체를 생성할 클래스의 위치(패키지명.클래스명)"
	    </bean>
	
	 -->
	
	<!-- 
	     com.sist.di02 패키지에 있는 ExamDaoImpl 클래스를
	     "daoImpl" 아리는 id를 지정하여 객체(bean)를 생성한다는 의미.
	     ExamDaoImpl daoImpl = new ExamDaoImpl();
	 -->
	
	<bean id="daoImpl" class="com.sist.di02.ExamDaoImpl" />
	
</beans>

 

 



02_DI 

com.sist.di03

package com.sist.di03;

public interface DAO {

	void add();
	
}
package com.sist.di03;

public class MySqlDAO implements DAO {

	@Override
	public void add() {
		
		System.out.println("MySqlDAO 수행 중입니다.....");
		
	}

}
package com.sist.di03;

public class OracleDAO implements DAO {

	@Override
	public void add() {
		
		System.out.println("OracleDAO 수행 중입니다.....");
		
	}

}
package com.sist.di03;

public class ServiceImpl {

	private DAO dao;

	public DAO getDao() {
		return dao;
	}

	public void setDao(DAO dao) {
		this.dao = dao;
	}
	
	
	// 비지니스 로직
	public void biz() {
		this.dao.add();
	}
	
}
package com.sist.di03;

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

public class Main {

	public static void main(String[] args) {
		
		AbstractApplicationContext ctx = 
				new GenericXmlApplicationContext("classpath:mydao.xml");
		
		ServiceImpl service = (ServiceImpl)ctx.getBean("service");
		
		service.biz();
		
		ctx.close();

	}

}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	
	<bean id="mysql" class="com.sist.di03.MySqlDAO" />
	
	<bean id="oracle" class="com.sist.di03.OracleDAO" />
	
	<bean id="service" class="com.sist.di03.ServiceImpl">
	
		<property name="dao">
			<ref bean="oracle" />   <!--bean xml 파일만 바꾸면 됨 소스 코드를 자유롭게 바꿀 수 있 -->
		</property>
	
	</bean>
	
	
</beans>