**Spring의 IOC 이용 



1. IOC(Inversion of Control)란 무엇인가? 

객체 생성을 직접하지 않고 프레임워크나 컨테이너가 생성해 준 객체를 이용하는 것을 IOC(제어의 역전)이라고 합니다. 



2. IOC방법은 어떠한 방법이 있을까요 ? 

1.  어노테이션(@)을 이용하는 방법    AnnotationConfigApplicationContext, 

2.   XML 파일을 이용하는 2가지 방법이 있습니다. 

GenericXmlApplicationContext 클래스가 ApplicationContext 인터페이스를 implements 




3. 제어의 역전(IOC)에 대해 이해해 봅시다.

일반적인 프로그램에서의 오브젝트에 대한 제어는 오브젝트를 생성하고 그 오브젝트를 이용해서 작업을 수행하는 형태입니다.

예를 들어서 

ClassA 가 있고 이걸 Main에서 호출해서 사용하려면 

ClassA exm = new ClassA(); 형식으로 객체를 생성해야할 것입니다. 


하지만, 제어의 역전이란 앞에서의 코드처럼 직접 객체를 생성하지 않고 다른 곳에서 생성해 준 객체를 가지고 작업을 수행하는 방식입니다.


4. 이러한 예는 서블릿에서도 찾을 수 있다. 

Eclipse 기반의 톰캣 컨테이너를 사용하는 프로젝트에서 서블릿은 직접 생성자를 호출해서 객체를 생성한 적이 없는데 

클라이언트의 요청이 오면 서블릿 객체의 doGet이나 doPost 메소드가 호출되는데 

이는 서블릿 객체에 대한 제어 권한을 컨테이너가 소유하고 있어서 적절한 시점에 서블릿 클래스의 오브젝트를 생성하고 

그 안의 메소드를 호출해주는 형태로 동작하기 때문인데 이러한 방식을 제어의 역전이라고 합니다.


프레임워크나 Connection Pool 이용한 데이터베이스 활용도 제어의 역전을 활용한 예로 객체 생성 시 객체의 생성자를 직접 호출하지 않습니다.



IOC(제어의 역전 활용해봅시다. )


1. 어노테이션 방법 


1
2
3
4
5
6
7
8
9
10
//팩토리 클래스로 만들어주는 어노테이션
@Configuration
public class GoodDaoFactory {
    //GoodDao 클래스의 객체 생성 메소드를 호출해서 리턴
    //객체를 생성해주는 메소드라는 어노테이션
    @Bean
    public static GoodDao create() {
        return new GoodDao();
    }
}
cs



2. 메인 클래스 생성 


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
package main;
 
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 
import dao.GoodDao;
import dao.GoodDaoFactory;
 
public class Main {
 
    //Java 응용 프로그램에서 사용되는 entry point(진입점)
    //Java 응용 프로그램을 실행하면 이 메소드가 호출됩니다.
    public static void main(String[] args) {
              
        //스프링의 annotation을 이용해서 객체 생성 
        //팩토리 클래스 지정 
        AnnotationConfigApplicationContext applicationContext = 
                new AnnotationConfigApplicationContext(GoodDaoFactory.class);
        
        //객체 생성 
        GoodDao goodDao = applicationContext.getBean("create",GoodDao.class);
        
        //메소드 호출 
        System.out.println(goodDao.getGood("001"));
        
        
    }
}
cs




**XML 파일을 이용한 Bean 설정 (IOC)  


Spring Bean Configuration 파일을 만들어서 bean 태그를 이용해서 설정하면 어노테이션을 이용했던 것처럼 사용할 수 있습니다. 

이 방법이 더 많이 사용됩니다. 

=> Spring Bean Configuration파일은 beans 태그로 시작해야합니다. 


1. beans 태그 

beans 태그를 만들 때 네임스페이스 또는 xml 스키마 관련 정보를 같이 넣어야 합니다. 

하위 태그로는 <bean>, <import>, <decription>,  <alias> 등이 있습니다. 


1-1) bean 태그 : 객체를 생성하기 위한 태그 

2) import 태그 : 설정해야 할 내용이 많을 때나 여러 곳에서 공통으로 사용하는 설정이 있을 때 다른 파일에 설정 내용을 작성하고 

호출해서 사용하기 위한 태그 

<import resource="다른 설정 파일 경로"/>



2. bean 태그를 이용해서 객체 생성 

1) spring bean configuration 파일에 bean 태그를 추가 

<bean id ="구별 아이디" class="객체를 생성할 클래스 경로 "> </bean>


2-1) 가져다가 사용할 파일에 추가 

GenericeXmlApplicationContext  변수명 = new GenericXmlApplicationContext("스프링 설정파일 경로");

클래스 이름 객체 변수명 = 변수명.getBean("구별할 아이디", 클래스이름.class);




실습해봅시다. 

1. Spring에서   spring legacy project를 생성한 후 


2. src/main/ resource에 오른쪽 클릭 New => Spring Bean Configuration


3. 파일 이름은  : applicationContext.xml 설정 


1
2
3
4
5
6
7
8
9
10
 
<?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">

<!-- GoodDao 클래스의 객체를 goodDao라는 이름으로 생성 -->
    <bean id = "goodDao" class="dao.GoodDao" destroy-method=""></bean>
    
</beans>
cs


1
2
3
4
5
6
7
8
// 메인에서 실행

GenericXmlApplicationContext context =
 new GenericXmlApplicationContext("classpath:applicationContext.xml");
 
객체 생성         
GoodDao goodDao = context.getBean("goodDao", GoodDao.class);    //xml 파일에설정한 class태그에서 .다음클래스이름 가져오면됩니다. 
System.out.println(goodDao.getGood("001"));
context.close();
 
cs








이 글에서 사용한 클래스 내용 


dao. ClassDAO


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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package dao;
 
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
 
import domain.Good;
 
public class GoodDao{
 
    Connection con;
    PreparedStatement pstmt;
    ResultSet rs;
 
    public GoodDao() {
        System.out.println("생성자");
    }
 
    public void init() {
        System.out.println("초기화 메소드");
    }
 
    // 문자열로 된 code를 입력받아서 goods 테이블에서 데이터를
    // 찾아서 리턴하는 메소드
    public Good getGood(String code) {
 
        Good good = null;
        // 문제가 발생할 가능성이 있는 코드
        try {
            // 오라클 드라이버 클래스 로드
            Class.forName("oracle.jdbc.driver.OracleDriver");
            // 데이터베이스 연결
            con = DriverManager.getConnection("jdbc:oracle:thin:@192.168.0.200:1521:xe""user08""user08");
 
            // goods 테이블에서 code를 가지고 테이터를 조회하는 sql
            pstmt = con.prepareStatement("select *from goods where code =? ");
            pstmt.setString(1, code);
 
            // SQL 실행
            rs = pstmt.executeQuery();
            if (rs.next()) {
                good = 
                good.setCode(rs.getString("code"));
                good.setName(rs.getString("name"));
                good.setManufacture(rs.getString("manufacture"));
                good.setPrice(rs.getInt("price"));
            }
            // 문제가 발생했을 때 수행할 코드
        } catch (Exception e) {
            System.out.println("[Dao] get메소드 예외 " + e.getMessage());
            e.printStackTrace();
            // 무조건 수행할 코드
            // 프로그램은 필연적으로 예측할 수없는 예외가 생길 수 있습니다.
            // 프로그램은 예외가 생겨도 팅기면 안되기 때문에 try catch를 씁니ㅏㄷ.
        } finally {
 
            try {
                if (rs != null)
                    rs.close();
                if (pstmt != null)
                    pstmt.close();
                if (con != null)
                    con.close();
            } catch (SQLException e) {
                System.out.println("[DAO]닫기 예외" + e.getMessage());
                e.printStackTrace();
            }
 
        }
        return good;
    }
 
}
cs





domain.Good


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
52
53
54
55
package domain;
 
 
 
public class Good  {
    //데이터를 저장하기 위한 변수 
    //private : 객체가 사용할 수 없음 
    private String code;
    private String name;
    private String manufacture;
    private  int price;
    
    public  Good(String code) {
        this.code = code; 
    }
    //객체가 변수를 사용할 수 있도록 해주는 메소드 
    //일반 변수는 동기화 제어를 할 수 없지만 메소드는 가능합니다. 
    // 동시에 같이 쓸 수 있다. 
    
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getManufacture() {
        return manufacture;
    }
    public void setManufacture(String manufacture) {
        this.manufacture = manufacture;
    }
    public int getPrice() {
        return price;
    }
    public void setPrice(int price) {
        this.price = price;
    }
    
    
    
    
    @Override
    public String toString() {
        return "Good [code=" + code + ", name=" + name + ", manufacture=" + manufacture + ", price=" + price + "]";
    }
    
    
}
 
cs




applicationContext.xml 


1
<bean id = "goodDao" class="dao.GoodDao" init-method="init" lazy-init="true"></bean>
cs


'Java > 스프링' 카테고리의 다른 글

Spring 2-2 TEST 디렉토리 사용  (0) 2018.04.09
Spring 2-1 Property(속성)  (0) 2018.04.09
Spring 1- 2 DI와 IOC ,@Component @Bean 사용 정리  (0) 2018.04.06
DI(Dependency Injection)  (0) 2018.04.05
1. Spring의 정의와 특징  (0) 2018.04.05

+ Recent posts