22.06.02
JAVA의 Class 상속 / Interface 를 이용한 추상화를 기반으로 하는 개발 방법.
Spring은 아래 DI / IoC를 강력하게 지원하는 프레임워크이다.
스프링은 DI를 기준으로 많은 프레임워크모듈 들이 만들어짐.
프로그램을 제어하는 패턴 중 하나.
DI는 IoC패턴의 구현방법 중 하나.
DI에 따라 프로그램의 흐름이 완전이 변경됨.
스프링 Conrainer 에 만들어둔 각종 클래스(bean)들은 서로 의존적이다.
A객체가 B객체 없이 동작이 불가능한 상황.
즉 객체 안에 객체가 저장되는 형태이다
- 제어의 역전
- 객체를 필요할 때 생성해서 사용하던 방식을
미리 생성해 놓고 꺼내서 사용하는 형태로 변경
스프링 Container 에 만들어둔 각종 클래스(bean)들은 서로 의존적이다.
서로 연관되어 있는 Hotel, Restaurant, Chef 클래스들을 이용.
Main에서 그냥 Hotel객체만 생성해서 부르면 다른 객체들은 생성되지 않았기 때문에 NullPointerException이 발생한다.
따라서 생성자,setter메서드를 이용해 명시해주어야 메서드가 실행됨.
<script>
public class Hotel {
private Restaurant res;
public Hotel(Restaurant res) {
System.out.println("호텔이 생성됨!");
this.res = res;
}
//실제 객체를 생성해야 사용할 수 있음. 생성자를 이용하는 방법
public void reserveRestaurant() {
System.out.println("레스토랑을 예약합니다.");
res.orderDinner();
}
}
</script>
<script>
public class Restaurant {
private Chef chef;
public Restaurant() {
System.out.println("레스토랑이 생성됨!");
}
public void setChef(Chef chef) {
this.chef = chef;
}
//실제 객체를 생성해야 사용할 수 있음. set메서드를 이용하는 방법
public void orderDinner() {
System.out.println("저녁 식사를 주문받습니다.");
chef.cook();
}
}
</script>
<script>
public class Chef {
public Chef() {
System.out.println("요리사가 생성됨!");
}
public void cook() {
System.out.println("요리사가 요리를 합니다!");
}
}
</script>
<script>
public class MainClass {
public static void main(String[] args) {
//평소방식 객체 다 직접생성
Chef chef = new Chef();
Restaurant res = new Restaurant();
res.setChef(chef);
Hotel hotel = new Hotel(res);
hotel.reserveRestaurant();
}
}
</script>
xml에 객체들을 미리 등록해놓고 Hotel만 불러온다.
# 2가지 의존성 주입 방법
1.생성자를 통한 의존성 주입
<constructor-arg ref="bean id">
2.setter를 통한 의존성 주입
<property name="변수명" value="값/>
<property name="변수명" ref="객체"/>
<!-- DI test -->
<!-- Hotel 객체와 의존객체들의 빈 등록 및 의존성 주입 -->
<bean id="chef" class="basic.ex01.Chef"/>
//setter를 통한 의존객체 주입
<bean id="res" class="basic.ex01.Restaurant">
<property name="chef" ref="chef"/>
<!-- 의존 객체 주입 name="변수명" ref="주입할 객체의 id"
관례적으로 setter메서드 이름은 set+변수명으로 해야함.-->
<!-- property name="set을 제외한 setter 메서드의 이름"
setter 메서드의 이름은 대부분 관례적으로 set + 멤버변수 이름 이기 때문에
변수명이라고 편하게 얘기하는 것이다. 사실을 setter메서드의 이름이 들어가는게 맞다. -->
</bean>
//생성자를 통한 의존객체 주입
<bean id="hotel" class="basic.ex01.Hotel">
<constructor-arg ref="res" />
<!-- 의존 객체 주입 ref="주입할 객체의 id" -->
</bean>
<script>
//스프링
//test-config.xml에 객체와 의존객체들의 빈 등록 및 의존성 주입 완료 후 호출하면 객체 생성없이 실행가능.
GenericXmlApplicationContext ct =
new GenericXmlApplicationContext("classpath:test-config.xml");
Hotel hotel = ct.getBean("hotel", Hotel.class);
hotel.reserveRestaurant();
ct.close();
</script>
데이터베이스 연동을 위한 로그인 작업이 필요하다고 할때,
xml에 등록해놓고 참조id만 바꿔주면 빠르게 진행할 수 있다.
객체 : ref
값 : value
<property name="dbInfo" ref="db1"/>
<property name="uid" value="spring2"/>
<script>
public class DataBaseInfo {
private String url;
private String uid;
private String upw;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getUpw() {
return upw;
}
public void setUpw(String upw) {
this.upw = upw;
}
}
</script>
<script>
public class MemberDAO {
private DataBaseInfo dbInfo;
public void setDbInfo(DataBaseInfo dbInfo) {
this.dbInfo = dbInfo;
}
public void showDBInfo() {
System.out.println("URL: " + dbInfo.getUrl());
System.out.println("UID: " + dbInfo.getUid());
System.out.println("UPW: " + dbInfo.getUpw());
}
}
</script>
<?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">
<!-- oracle -->
<bean id="db1" class="basic.ex02.DataBaseInfo">
<!-- setter 주입(객체말고 값) -->
<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
<property name="uid" value="spring"/>
<property name="upw" value="sss123"/>
</bean>
<!-- mysql -->
<bean id="db2" class="basic.ex02.DataBaseInfo">
<!-- setter 주입(객체말고 값) -->
<property name="url" value="jdbc:mysql://localhost:3306@spring"/>
<property name="uid" value="spring2"/>
<property name="upw" value="sss222"/>
</bean>
<bean id="dao" class="basic.ex02.MemberDAO">
<property name="dbInfo" ref="db1"/>
<!-- 참조(ref) id만 바꿔주면 oracle,mysql 자유롭게 이동가능 -->
</bean>
</beans>
<script>
public class MainClass {
public static void main(String[] args) {
GenericXmlApplicationContext ct =
new GenericXmlApplicationContext("classpath:db-config.xml");
MemberDAO dao = ct.getBean("dao",MemberDAO.class);
dao.showDBInfo();
ct.close();
}
}
</script>
콘솔에 내용 바로 출력 가능.
URL: jdbc:oracle:thin:@localhost:1521:xe
UID: spring
UPW: sss123