JdbcTemplate 클래스


=>Spring JDBC 클래스

=>sql의 매개변수를 Object [] 을 이용해서 매핑하는 클래스



[생성자]

JdbcTemplate(DataSource dataSource)


[select 구문을 수행해주는 메소드]


[select 구문의 결과가 여러 개의 행일 때 사용]


List query(String sql, RowMapper rowMapper)

List query(String sql, Object [] args, RowMapper rowMapper)



[select 구문의 결과가 하나의 행일 때 사용]

Object queryForObject(String sql, RowMapper rowMapper)

Object queryForObject(String sql, Object [] args, RowMapper rowMapper)


[select 구문의 결과가 하나의 행일 때 하나의 Map 에 결과를 저장하고자 하는 경우 사용]

Map<String, Object> queryForMap(String sql)

Map<String, Object> queryForMpa(String sql, Object [] args)


[RowMapper 인터페이스]

=>select 구문의 결과로 반환되는 하나의 행을 객체로 만들기 위한 메소드를 소유한 인터페이스

=>mapRow(ResultSet rs, int rownum) 추상 메소드를 소유

=>rs는 하나의 행을 저장한 객체이고 rownum은 행 번호를 저장한 정수



[JdbcTemplate 클래스를 이용한 테이블의 데이터 읽기]

1.spring-jdbc 라이브러리 다운로드
=>pom.xml 파일에 spring-jdbc 의존성 확인

2.spring 설정 파일(bean configuration 파일 - applicationContext.xml)에 DataSource 빈이 추가되어 있는지 확인




3.샘플 테이블 및 데이터 생성

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
--스쿨버스를 위한 db설계 
-- busnum , name , price , sysdate
 
--시퀀스 생성 
create sequence busnumseq;
 
--테이블 생성 
create table schoolbus(
busnumber number(10primary key,
name varchar2(20not null,
price number(10),
writedate date default sysdate
);
 
--샘플데이터
insert into schoolbus (busnumber, name, price, writedate ) values(busnumseq.nextval, '붕붕카'300, sysdate);
insert into schoolbus (busnumber, name, price, writedate ) values(busnumseq.nextval, '서울카'500, sysdate);
 
--데이터 확인 
select *
from schoolbus;
 
--작업완료 
commit
 
cs


4. JdbcTeplate  클래스의 객체를 소유한 Dao 클래스 생성 dao.schoolbus


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
package dao;
 
import java.util.Map;
 
import org.springframework.jdbc.core.JdbcTemplate;
 
public class SchoolBus {
    // Spring JDBC 기본 클래스
    private JdbcTemplate jdbcTemplate;
 
    public JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }
 
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
 
    // 데이터의 개수를 알려주는 메소드
    public Map<String, Object> count() {
        // 하나의 행만 리턴하는 select 구문 수행
        return jdbcTemplate.queryForMap("select count(*) from schoolbus");
 
    }
}
 
 
cs


5. spring 설정파일에 SchoolBus 객체를 만들기  

1
2
3
4
5
6
7
8
9
10
11
<bean class="org.springframework.jdbc.core.JdbcTemplate" id = "jdbcTemplate">
        <!--  생성자 주입  -->
        <constructor-arg ref= "dataSource"></constructor-arg>
    </bean>
    
    
    <!-- school 클래스의 객체를 생성 IOC -->
    <bean class ="dao.SchoolBus" id="shcoolbus">
    <!-- jdbcTemplate이라는  id를 가진 bean을 jdbcTemplate 이라는 프로퍼티에 주입 :DI  -->
    <property name="jdbcTemplate" ref ="jdbcTemplate"></property>
    </bean>
cs


6.main 메소드를 소유한 Main 클래스를 만들고 main 메소드 실행


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import org.springframework.context.support.GenericXmlApplicationContext;
 
import dao.SchoolBus;
 
public class Main {
 
    public static void main(String[] args) {
        GenericXmlApplicationContext context = 
            new GenericXmlApplicationContext(
                            "classpath:applicationContext.xml");
        SchoolBus bus = context.getBean(SchoolBus.class);
        //select 절에 쓴 내용을 적기 
        System.out.println(bus.count().get("COUNT(*)"));
    }
 
}
 
cs






Spring 2-2 JUnit 사용 




=>src/test/java 디렉토리에 클래스를 만들면 배포할 때는 사라지는 클래스를 만들 수 있습니다.

=>테스트 하고자 하는 모듈이 있을 때는 src/test/java 디렉토리에 클래스를 하나 만들고 그 클래스 안에 @Test라는 어노테이션과 함께 메소드를 만들면 테스트 가능한 메소드를 만들어서 테스트 할 수 있습니다.


1.Simple Spring Maven Project를 생성


2.Java 버전 변경

1)프로젝트를 선택하고 마우스 오른쪽을 클릭해서 [Properties]를 실행하고 Project Facets에서 버전 변경


2)pom.xml 파일에서 java version 변경

<java.version>1.8</java.version>


3.pom.xml 파일에서 Spring Version 변경

4.2.4, 4.1.0, 4.0.4, 4.0.1 등으로 변경


<spring-framework.version>4.2.4.RELEASE</spring-framework.version>


4.pom.xml 파일에 오라클 사용을 위한 의존성 라이브러리 설정을 추가

1)오라클은 중앙 저장소에서 다운로드 받을 수 없어서 repositories를 설정해야 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- 라이브러리 다운로드 받을 저장소 설정 -->
 
<repositories>
 
    <repository>
 
        <id>codelds</id>
 
        <url>https://code.lds.org/nexus/content/groups/main-repo</url>
 
    </repository>
 
</repositories>
cs


2)오라클 라이브러리 다운로드 코드를 <dependencies> 태그 안에 추가

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- 오라클 라이브러리 의존성 설정 -->
 
<dependency>
 
    <groupId>com.oracle</groupId>
 
    <artifactId>ojdbc6</artifactId>
 
    <version>11.2.0.3</version>
 
</dependency>
 
 
cs


5. src/test/java 에 테스트 용으로 사용할 클래스를 생성 : ConnectionTest


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
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
 
import org.junit.Test;
 
public class ConnectionTest {
 
    // 테스트를 수행할 메소드
    @Test
    public void connect() {
        // 1. 데이터 베이스 연동 클래스 로드
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
 
        } catch (ClassNotFoundException e) {
            // 이 메시지가 출력되면 드라이버 클래스 이름을 잘못 했거나
            // 라이브러리가 다운로드 되지 않은 경우입니다.
            System.out.println("[TEST] DB 연결 " + e.getMessage());
            e.printStackTrace();
        }
 
        // 2. 데이터 베이스 연결
        // try() 안에 연결하면 해제 할 필요가 없습니다.
        // 이 문법은 java1.7 이상에서 사용이 가능합니다.
        try (Connection con = DriverManager.getConnection("jdbc:oracle:thin:@192.168.0.200:1521:xe"
                "user08","user08")) {
        } catch (SQLException e) {
            System.out.println("[연결]" + e.getMessage());
            e.printStackTrace();
        }
 
    }
}
cs


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

스프링 Mybatis를 XML DB 연결  (0) 2018.04.12
JdbcTemplate 클래스  (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


[Java 코드로만 데이터베이스를 사용 ]

=>Connection, Statement, ResultSet을 이용해서 사용 

=> 프레임워크를 이용하지 않기 때문에 프레임워크의 변화에 아무런 영향도 받지 않습니다. 

=> 디자인 패턴이나 코드 최적화를 하지 않으면 비효율적이 프로그램이 만들어집니다. 

=> 디자인 패턴이나 알고리즘 및 자료구조 공부를 많이 한 경우에 사용합니다. 


[프레임워크를 이용하는 방법 ]

=> 알고리즘이나 디자인 패턴 및 자료구조를 심도있게 공부하지 않아도 무난한 데이터베이스 연동 프로그램을 만들수 있습니다. 


1) SQL Mapper Freamwork : SQL을 별도로 작성하고 실행해서 결과를 가져오는 방식으로 파라미터 매핑이나 결과 매핑은 프레임워크가 대신 해줍니다. 

이 방식의 대표적인 프레임워크는 MyBatis(iBatis)가 있습니다.  

구현 방법이 쉽기 때문에 현재 우리나라 공공기관 프로젝트나 금융기관 프로젝트가 많이 사용하고 있습니다. 


2) Object Relationship Mapping Framework :테이블과 클래스를 매핑시켜서 SQL 없이 데이터 베이스 작업을 수행하는 방식입니다. 

이 방식의 대표적이 프레임워크는 Hibernate - JPA가 있습니다. 

구현은 어렵지만 성능 SQL Mapper보다 우수합니다. 

SI(시스템 통합)에는 부적합하고 일반 application 개발에 주로 이용 




Property(속성) 



Property(속성) 란 무엇인가요 ? 

=> 일반적으로 DTO(Data Transfer Object) 또는 VO(Value Obejct) 에서 볼 수 있다. 

=> 인스턴스 변수와 getter와 setter로 만들어진 형태 


[Properties ]

=> 키와 값을 쌍으로 갖는 자료구조 또는 파일입니다. 

=> 키와 값을 자료형이 모두 String(문자열) 입니다. 

=> 변경 가능성이 있는 문자열을 별도의 properties 파일에 작성해두고 프로그램 내에서 호출하는 형태로 많이 사용합니다. 

=> 변경 가능성이 있는 문자열을 String 타입의 객체에 저장해두고 사용하면 수정을 할 때 컴파일을 다시해서 실행시켜야합니다. 

=> 컴파일을 다시해서 실행하게 되면 시간이 오래 걸리게 되면 컴파일을 하다 예기치 못한 오류를 발생가능성이 있습니다.

=> 별도의 파일이나 테이터베이스를 이용하게 되면 컴파일을 다시 하지 않고 재실행 만으로 변경 내용을 적용할 수 있기 때문에 

예기치 못한 오류를 발생시킬 가능성이 줄어들게 됩니다. 



[유의사항]

=>properties 작성할 때 유의할 점은 utf-8로 인코딩해서 작성해야 하는 것입니다. 

=>eclipse에서는 text file이나 encoding 옵션을 utf-8로 설정 해두고 작업을 하는 것이 편리합니다. 



[예제를 하나 만들어 봅시다]

준비 :  기본적인 오라클 셋팅은 되어 있어야합니다. 


1. Simple Spring Maven Project 생성 

2. 프로젝트를 선택하고 마우스 오른쪽 클릭하고 [Properties] - Project Facets  에서  java version변경 

3. pom.xml 파일에서 Spring version을 4.x.x로 변경 

4. src/main/resources 디렉토리에 db.properties 파일을 생성 


1
2
user.email=ggangpae1@naver.com
user.name=관리자 
cs


5. main클래스에서 properties 불러보기  


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
package main;
 
import java.io.IOException;
 
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.io.support.ResourcePropertySource;
 
public class Main {
 
    // 응용 프로그램이 호출할 수 있는 유일한 메소드 모양입니다.
    public static void main(String[] args) {
 
        // 자바의 프로퍼티
 
        // ApplicationContext 객체 만들기
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
 
        // 시스템 프로퍼티를 읽을 수 있는 객체를 생성
        ConfigurableEnvironment env = (ConfigurableEnvironment) context.getEnvironment();
 
        // Property 파일의 내용을 읽을 수 있는 객체를 생성
        MutablePropertySources pSource = env.getPropertySources();
 
        // 프로퍼티 파일 연결
        try {
            pSource.addFirst(new ResourcePropertySource("classpath:user.properties"));
            
            
            System.out.println("이메일:"+env.getProperty("user.email"));
            System.out.println("이메일:"+env.getProperty("user.name"));
            
 
        } catch (IOException e) {
            System.out.println("[Main] Property 예외" + e.getMessage());
            e.printStackTrace();
        }
 
        // applicationContext 객체 닫기
        context.close();
    }
 
}
cs


[ 스프링 설정 파일에 properties 파일 읽기  ]


설정파일은     SpringBeanConfiguration 파일을 src/main/resources 디렉토리에 생성합니다. 

<context:property-placeholder location=“classpath:/프로퍼티파일 경로"/> 

태그를 스프링 설정 파일에 추가하고 ${프로퍼티 파일의 키}를 작성하면 프로퍼티 파일에서 키에 해당하는 문자열을 가져와서 출력을 하게 됩니다. 


1.src/main/resources 디렉토리에 db.properties 파일을 만들고 db 접속 정보를 프로퍼티로 생성

1
2
3
4
5
6

 
db.driver=oracle.jdbc.driver.OracleDriver
db.url=jdbc:oracle:thin:@localhost:1521:xe
db.user=user08
db.password=user08
cs



2.driver, url, user, password를 프로퍼티(인스턴스 변수, getter, setter)로 갖는 db.Dao 클래스를 생성


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
package domain;
 
public class DbVo {
 
    
    
    private String driver; 
    private String url; 
    private String user; 
    private String password;
    
    public String getDriver() {
        return driver;
    }
    public void setDriver(String driver) {
        this.driver = driver;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public String getUser() {
        return user;
    }
    public void setUser(String user) {
        this.user = user;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    
    
    @Override
    public String toString() {
        return "DbVo [driver=" + driver + ", url=" + url + ", user=" + user + ", password=" + password + "]";
    } 
    
    
    
}
cs


3.SpringBeanConfiguration 파일을 src/main/resources 디렉토리에 생성하고 Dao 클래스의 객체를 만드는 코드를 추가

1)context 네임스페이스 추가


2)프로퍼티 파일의 내용을 읽을 수 있는 태그 추가

1
<context:property-placeholder location="classpath:/db.properties" />
cs

3)Dao 클래스의 bean을 생성하는 코드를 추가하고 property에 db.properties 파일의 내용을 설정하는 코드를 작성 - DI

1
2
3
4
5
6
7
8
9
10
    <!-- db.Dao 클래스의 객체를 생성하는 코드 -->
    <bean id="dao" class="db.Dao">
        <!-- driver 라는 프로퍼티에 db.properties 파일에 작성한
        db.driver 라는 키의 값을 대입 -->
        <property name="driver" value="${db.driver}" />
        <property name="url" value="${db.url}" />
        <property name="user" value="${db.user}" />
        <property name="password" value="${db.password}" />
    </bean>
 
cs


4.main 메소드의 내용을 수정해서 dao 빈의 내용을 출력

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//응용 프로그램이 호출할 수 있는 유일한 메소드 모양입니다.
    public static void main(String[] args){
        
        //ApplicationContext 객체 만들기
        GenericXmlApplicationContext context = 
            new GenericXmlApplicationContext(
                "classpath:applicationContext.xml");
        
        //db.Dao 클래스의 bean 가져오기
        Dao dao = context.getBean(Dao.class);
        System.out.println(dao);
        
        
        //ApplicationContext 객체 닫기
        context.close();
        
    }
 
cs


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

JdbcTemplate 클래스  (0) 2018.04.09
Spring 2-2 TEST 디렉토리 사용  (0) 2018.04.09
Spring 1- 2 DI와 IOC ,@Component @Bean 사용 정리  (0) 2018.04.06
DI(Dependency Injection)  (0) 2018.04.05
Spring 1-1) IOC 제어의 역전  (0) 2018.04.05

**IoC(Inversion Of Control - 제어의 역전)

=>객체지향 프로그래밍의 기본적인 원리는 클래스를 만들고 이 클래스로부터 객체를 생성해서 사용하는 것입니다.

=>사용하려는 객체의 용도 또는 방법에 따라서 클래스를 디자인 해야 합니다.

=>이렇게 클래스를 사용하려는 용도나 방법에 따라 디자인 하는 것을 디자인 패턴이라고 합니다.

=>클래스는 일반적인 형태로 비지니스 로직만 구현하도록 개발자가 만들고 디자인 패턴의 적용은 컨테이너나 프레임워크가 해서 객체를 만들어주는 방식

=>Spring에선느 IoC의 구현을 어노테이션(@ - 결국은 자바코드로 변환)을 이용하는 방법과 xml 파일을 이용하는 방법(자바 코드로 변환) 2가지를 제공합니다.

1.xml 파일에 객체를 생성하는 코드

<bean class="객체를 생성하고자 하는 클래스의 전체 경로" id="구분하는 이름"></bean>

2.application project 일 때는 xml 파일을 직접 읽지만 web project일 때는 web.xml 파일에 xml 파일을 읽도록 설정을 합니다.

=>직접 읽어서 객체를 생성하기

1
GenericXmlApplicationContext 변수 = new GenericXmlApplicationContext("xml 파일 경로");
cs

=>파일 경로는 classpath:파일경로를 적는데 classpath는 src/main/resources 또는 src/main/java 인데 나중에 두 개의 디렉토리는 하나로 합쳐지기 때문에 위치는 관계없습니다.

=>파일을 읽으면 bean 태그로 만들어진 객체들은 전부 싱글톤 패턴으로 생성됩니다.

3.bean으로 만들어진 객체 사용

1
자료형 객체이름 = 변수.getBean("bean의 아이디", 클래스이름.class);
cs

=>getBean을 호출할 때 아이디를 생략하면 클래스이름으로 만들어진 bean을 찾아서 대입

=>bean의 아이디만 입력하고 클래스이름을 생략하면 이 때는 Object 타입으로 리턴되기 때문에 강제 형 변환을 해서 사용해야 합니다.

**IoC 실습

1.Simple Spring Maven Project 를 생성

2.pom.xml 파일에서 Spring Version 변경 - 4.2.4, 4.1.0, 4.0.4, 4.0.1

<!-- Spring -->

1
<spring-framework.version>4.2.4.RELEASE</spring-framework.version>
cs

3.Java Version 변경

=>프로젝트를 선택하고 마우스 오른쪽을 클릭해서 [Properties]

=>[Project Facets]에서 Java Version 변경

1.1 -> 1.2 -> 1.5(Generic, Annotation) -> 1.8(Lambda, stream API)

      -> 1.6(현재 전자정부 프레임워크 표준) -> 1.8

4.IoC 와 DI에 이용할 VO 클래스 생성 - domain.MemberVO

1
2
3
package domain;
public class MemberVO {
    private String email;
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private String name;
 
        //email 과 name 프로퍼티 생성
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    
    //디버깅을 위한 메소드
    @Override
    public String toString() {
        return "MemberVO [email=" + email + ", name=" + name + "]";
    }
    }
cs

5.bean을 만들어주는 Spring Bean Configuration 파일을 생성하고 MemberVO 클래스의 bean 생성코드를 작성

=>src/main/resources 디렉토리에 applicationContext.xml

=>bean을 만들 때 id 설정은 대부분 클래스이름을 그대로 적고 첫 글자만 소문자로 변경하는 것이 관례입니다.

 

1
2
3
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
cs
1
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
cs
1
2
3
<bean id="memberVO" class="domain.MemberVO"></bean>
 
</beans>
cs

6.application을 실행할 수 있도록 하기 위해서 main 메소드를 소유한 클래스를 만들고 main 메소드에 5번에서 만든 applicationContext.xml 파일을 읽는 코드를 작성

1
import org.springframework.context.support.GenericXmlApplicationContext;
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import domain.MemberVO;
 
public class Main {
    public static void main(String[] args) {
        //스프링 빈 설정 파일을 읽어서 실행
        GenericXmlApplicationContext context = 
            new GenericXmlApplicationContext(
                "classpath:applicationContext.xml");
        //설정 파일에 만든 memberVO라는 id를 가진 bean을
        //MemberVO 타입으로 변환해서 가져오기
        MemberVO memberVO = 
            context.getBean("memberVO", MemberVO.class);
        
        memberVO.setEmail("ggangpae1@gmail.com");
        memberVO.setName("박문석");
        
        System.out.println(memberVO);
        
        //스프링 빈 설정 파일이 생성한 모든 객체 삭제하기
        context.close();
    }
}
cs

DI(Dependency Injection = 의존성 주입 ) 

=>의존성 주입(Dependency InjectionDI)은 프로그래밍에서 구성요소간의 의존 관계가 소스코드 내부가 아닌 외부의 설정파일 등을 통해 정의되게 하는 디자인 패턴 중의 하나이다. -위키피디아

=> 인스턴스 변수에 외부에서 생성한 데이터를 대입 

=> Contructor (생성자)를 이용하는 방법과 Property(setter)를 이용하는 방법 2가지가 있습니다. 

=> Constructor를 이용하는 방법은 객체를 생성할 때 외부에서 대입받는 것이고 Property를 이용하는 방법은 필요할 때 대입받는 방법입니다. 

=> Constructor를 이용하는 방법은 처음부터 만들어서 소유하고 있기 떄문에 호출 속도가 빠르다는 장점은 있지만무거워질 가능이 있습니다. 

Property를 이용하는 방법은 필요할 때 만들기 때문에 호출 속도가 느리다는 단점이 있지만 프로그램이 가벼워진다는 장점이 있습니다 .

1. 생성자를 이용하는 DI 

1
2
3
4
<bean id = "빈의 아이디" class="클래스 경로">
    <constructor-arg value="값"> </constructor-arg> 또는 
    <constructor-arg ref="다른 bean의 아이디"> </constructor-arg>
</bean>
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
/* Object super; */
    // Default Contructor 매개변수가 없는 생성자
    public MemberVo() {
        super(); // super =new Obejct(); this=new Member();
}
 
    // 그렇기에 그만 큼 속도에서 이득 볼수 있는게 생성자이다
    public MemberVo(String email) {
        super();
        this.email = email;
}
// 메서드 원형을 얘기할 때는 변수명은 안들어간다
 
    public MemberVo(String email, String name) {
        super();
        this.email = email;
        this.name = name;
}
 
    public MemberVo(String email, String name, String addr) {
        super();
        this.email = email;
        this.name = name;
        this.addr = addr;
    }
cs

3. applicationContext.xml 파일에 매개변수가 있는 생성자를 이용해서 bean을 만드는 코드를 추가 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<bean id="memberVo" class="domain.MemberVo"></bean>
 
<!-- new MemberVo(String email)로 생성 -->
<bean id="memberVo1" class="domain.MemberVo">
<constructor-arg value="jessica72@naver.com"></constructor-arg>
</bean>
 
<!-- new MemberVo(String email String name)로 생성 -->
<bean id="memberVo2" class="domain.MemberVo">
<constructor-arg value="hunt72@naver.com"></constructor-arg>
<constructor-arg value="헌트"></constructor-arg>
</bean>
 
<!-- new MemberVo(String email, String name, String addr)로 생성 -->
<bean id="memberVo3" class="domain.MemberVo">
<constructor-arg value="tae72@naver.com"></constructor-arg>
<constructor-arg value="태연"></constructor-arg>
<constructor-arg value="한국"></constructor-arg>
</bean>
</beans>
cs

4. applicationContext.xml 파일에서 생성자의 매개변수에 값을 직접 대입하지 않고 다른 bean의 id를 대입해서 의존성 주입 

1
2
3
4
5
6
7
8
9
10
11
12
13
// ref와 value의 사용 때는 재사용을 해야할 것같을 때 ref, 
 
<bean id="memberVo3" class="domain.MemberVo">
<constructor-arg value="tae72@naver.com"></constructor-arg>
<!-- <constructor-arg value="태연"></constructor-arg> -->
<constructor-arg ref= "name"></constructor-arg>
<constructor-arg value="한국"></constructor-arg>
</bean>
 
<!-- String name = new String("헌트") 까지 한 것 -->
<bean id="name" class="java.lang.String">
    <constructor-arg value="태연"></constructor-arg>
</bean>
cs

6.main을 실행

====================================

****IoC 실습

1.Simple Spring Maven Project 를 생성

2.pom.xml 파일에서 Spring Version 변경 - 4.2.4, 4.1.0, 4.0.4, 4.0.1

<!-- Spring -->

<spring-framework.version>4.2.4.RELEASE</spring-framework.version>

3.Java Version 변경

=>프로젝트를 선택하고 마우스 오른쪽을 클릭해서 [Properties]

=>[Project Facets]에서 Java Version 변경

1.1 -> 1.2 -> 1.5(Generic, Annotation) -> 1.8(Lambda, stream API)

      -> 1.6(현재 전자정부 프레임워크 표준) -> 1.8

4.IoC 와 DI에 이용할 VO 클래스 생성 - domain.MemberVO

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
package domain;
 
public class MemberVO {
    private String email;
    private String name;
    
    //email 과 name 프로퍼티 생성
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    
    //디버깅을 위한 메소드
    @Override
    public String toString() {
        return "MemberVO [email=" + email + ", name=" + name + "]";
    }
    
    
}
cs

5.bean을 만들어주는 Spring Bean Configuration 파일을 생성하고 MemberVO 클래스의 bean 생성코드를 작성

=>src/main/resources 디렉토리에 applicationContext.xml

=>bean을 만들 때 id 설정은 대부분 클래스이름을 그대로 적고 첫 글자만 소문자로 변경하는 것이 관례입니다.

 

1
2
3
4
5
6
7
<?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="memberVO" class="domain.MemberVO"></bean>
 
</beans>
cs

6.application을 실행할 수 있도록 하기 위해서 main 메소드를 소유한 클래스를 만들고 main 메소드에 5번에서 만든 applicationContext.xml 파일을 읽는 코드를 작성

import org.springframework.context.support.GenericXmlApplicationContext;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import domain.MemberVO;
 
public class Main {
    public static void main(String[] args) {
        //스프링 빈 설정 파일을 읽어서 실행
        GenericXmlApplicationContext context = 
            new GenericXmlApplicationContext(
                "classpath:applicationContext.xml");
        //설정 파일에 만든 memberVO라는 id를 가진 bean을
        //MemberVO 타입으로 변환해서 가져오기
        MemberVO memberVO = 
            context.getBean("memberVO", MemberVO.class);
        
        memberVO.setEmail("ggangpae1@gmail.com");
        memberVO.setName("박문석");
        
        System.out.println(memberVO);
        
        //스프링 빈 설정 파일이 생성한 모든 객체 삭제하기
        context.close();
    }
}
cs

**DI(Dependency Injection = 의존성 주입 ) 

=> 인스턴스 변수에 외부에서 생성한 데이터를 대입 

=> Contructor (생성자)를 이용하는 방법과 Property(setter)를 이용하는 방법 2가지가 있습니다. 

=> Constructor를 이용하는 방법은 객체를 생성할 때 외부에서 대입받는 것이고 Property를 이용하는 방법은 필요할 때 대입받는 방법입니다. 

=> Constructor를 이용하는 방법은 처음부터 만들어서 소유하고 있기 떄문에 호출 속도가 빠르다는 장점은 있지만무거워질 가능이 있습니다. 

Property를 이용하는 방법은 필요할 때 만들기 때문에 호출 속도가 느리다는 단점이 있지만 프로그램이 가벼워진다는 장점이 있습니다 .

1. 생성자를 이용하는 DI 

1
2
3
4
<bean id = "빈의 아이디" class="클래스 경로">
    <constructor-arg value="값"> </constructor-arg> 또는 
    <constructor-arg ref="다른 bean의 아이디"> </constructor-arg>
</bean>
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
/* Object super; */
    // Default Contructor 매개변수가 없는 생성자
    public MemberVo() {
        super(); // super =new Obejct(); this=new Member();
}
 
    // 그렇기에 그만 큼 속도에서 이득 볼수 있는게 생성자이다
    public MemberVo(String email) {
        super();
        this.email = email;
}
// 메서드 원형을 얘기할 때는 변수명은 안들어간다
 
    public MemberVo(String email, String name) {
        super();
        this.email = email;
        this.name = name;
}
 
    public MemberVo(String email, String name, String addr) {
        super();
        this.email = email;
        this.name = name;
        this.addr = addr;
    }
cs

3. applicationContext.xml 파일에 매개변수가 있는 생성자를 이용해서 bean을 만드는 코드를 추가 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<bean id="memberVo" class="domain.MemberVo"></bean>
 
<!-- new MemberVo(String email)로 생성 -->
<bean id="memberVo1" class="domain.MemberVo">
<constructor-arg value="jessica72@naver.com"></constructor-arg>
</bean>
 
<!-- new MemberVo(String email String name)로 생성 -->
<bean id="memberVo2" class="domain.MemberVo">
<constructor-arg value="hunt72@naver.com"></constructor-arg>
<constructor-arg value="헌트"></constructor-arg>
</bean>
 
<!-- new MemberVo(String email, String name, String addr)로 생성 -->
<bean id="memberVo3" class="domain.MemberVo">
<constructor-arg value="tae72@naver.com"></constructor-arg>
<constructor-arg value="태연"></constructor-arg>
<constructor-arg value="한국"></constructor-arg>
</bean>
</beans>
cs

4. applicationContext.xml 파일에서 생성자의 매개변수에 값을 직접 대입하지 않고 다른 bean의 id를 대입해서 의존성 주입 

1
2
3
4
5
6
7
8
9
10
11
12
13
// ref와 value의 사용 때는 재사용을 해야할 것같을 때 ref, 
 
<bean id="memberVo3" class="domain.MemberVo">
<constructor-arg value="tae72@naver.com"></constructor-arg>
<!-- <constructor-arg value="태연"></constructor-arg> -->
<constructor-arg ref= "name"></constructor-arg>
<constructor-arg value="한국"></constructor-arg>
</bean>
 
<!-- String name = new String("헌트") 까지 한 것 -->
<bean id="name" class="java.lang.String">
    <constructor-arg value="태연"></constructor-arg>
</bean>
cs

6.main을 실행

====================================

**Property(변수 + getter 와 setter : 속성 ) 를 이요한 DI

====================================

=> set 메소드를 이용해서 인스턴스 변수에 데이터를 대입 

=> 생성자를 이용하는 것보다 느리게 만들어지지만 메모리 부담은 줄어듭니다. 

python과 C#에서는 변수.변수명 으로 불러서 프로퍼리를 할수 있게 해줍니다. 

1
2
3
4
<bean id="빈의 아이디" class="클래스의 경로">
<property name="프로퍼리이름" value="값"> </property>
<property name="프로퍼티이름" ref="다른 bean의 아이디"></property>
</bean>
cs

=>프로퍼티이름은 변수명이 아니며, setter 메소드에서 set을 제외하고 나머지 문자열의 

첫글자만 소문자로 변경합니다. 

=>MemberVo 는 2개의 프로퍼티가 존재합니다. 

1. applicationContext.xml 파일에 property에 의존성 주입하는 bean을 생성하는 코드를 작성 

1
2
3
4
5
6
7
8
9
<bean id = "memberVo4" class="domain.MemberVo">
<property name="email" value="tstigma@naver.com"></property>
<property name="name" ref="second"></property>
</bean>
 
<bean id = "second" class="java.lang.String">
<constructor-arg value="armor"></constructor-arg>
 
</bean>
cs

2.main 메소드에서 bean을 가져오는 코드를 작성하고 실행 

1
2
MemberVo memberVo4 = context.getBean("memberVo4",MemberVo.class);
System.out.println(memberVo4);
cs

======================================================

namespace

======================================================

**namespace(이름공간)를 이용하면 constructor-arg 나 property태그 대신에 bean을 생성하는 코드 내부에 속성으로 값을 대입할 수 있습니다. 

c와 p네임스페이스를 추가하면 됩니다. 

코드를 간결하게 만들기 위해 사용합니다. 

1.applicationContext.xml 파일에 c와 p 네임스페이스 추가

2.applicationContext.xml 파일에 c와 p 네임스페이스를 이용한 bean 생성 코드 추가

1
2
3
4
5
6
7
8
9
10
<!-- MemberVO memberVO4 = 
        new MemberVO("abc@gmail.com""조헌"); -->
    <bean id="memberVO4" class="domain.MemberVO"
    c:email="abc@gmail.com" c:name="조헌"/>
    
    <!-- MemberVO memberVO5 = new MemberVO(); 
    memberVO5.setEmail("efg@gmail.com");
    memberVO5.setName("강감찬")-->
    <bean id="memberVO5" class="domain.MemberVO"
    p:email="efg@gmail.com" p:name="강감찬" />
cs

=======================================================

Collection을 주입받기 위한 예제 

1. 4개의 Collection을 인스턴스 변수로 갖는 클래스 생성 

domain.CollectionDI


2.SpringBeanConfiguration 파일을 생성하고 CollectionDI 객체를 생성해주는 bean 코드를 추가

=>src/main/resources 디렉토리의 collection.xml

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
<?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="collectionDI" class="domain.CollectionDI">
        <property name="list">
            <list>
                <value>배열</value>
                <value>ArrayList</value>
                <value>LinkedList</value>
                <value>Stack</value>
                <value>Queue</value>
                <value>Deque</value>
            </list>
        </property>
        
        <property name="set">
            <set>
                <value>HashSet</value>
                <value>LinkedHashSet</value>
                <value>TreeSet</value>
            </set>
        </property>
        
        <property name="properties">
            <props>
                <prop key="Encapsulation">캡슐화</prop>
                <prop key="Inheritance">상속성</prop>
                <prop key="Polymorphism">다형성</prop>
            </props>
        </property>
        
        <property name="map">
            <map>
                <entry>
                    <key><value>Encapsulation</value></key>
                    <value>클래스를 만드는 것</value>
                </entry>
                <entry>
                    <key><value>Inheritance</value></key>
                    <value>하위 클래스가 상위 클래스의 모든 것을
                    물려받는 것</value>
                </entry>
                <entry>
                    <key><value>Polymorphism</value></key>
                    <value>동일한 메시지에 대하여 다르게
                    반응하는 성질</value>
                </entry>
            </map>
        </property>
</bean>
 
</beans>
cs

**일반적인 프로그램 구조 

domain class, DAO---> Service ----> Controller --- > View

=>ApplicationProgramming 에서는 Controller의 역할을 Main이 합니다. 

1. spring과 java version 바꿉니다. 

2. Spring과 Java 버전 설정 

3. VO로 사용할 클래스 생성 

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
package domain;
public class Board {
 
    
    private int num ; 
    private String id;
    private String name;
    private String subject;
    private String content;
    private int readcount; 
    private String writedate ; //작성일 ㅁ
    public int getNum() {
        return num;
    }
    public void setNum(int num) {
        this.num = num;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSubject() {
        return subject;
    }
    public void setSubject(String subject) {
        this.subject = subject;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public int getReadcount() {
        return readcount;
    }
    public void setReadcount(int readcount) {
        this.readcount = readcount;
    }
    public String getWritedate() {
        return writedate;
    }
    public void setWritedate(String writedate) {
        this.writedate = writedate;
    }
    
    
    @Override
    public String toString() {
        return "Board [num=" + num + ", id=" + id + ", name=" + name + ", subject=" + subject + ", content=" + content
                + ", readcount=" + readcount + ", writedate=" + writedate + "]";
    }
    
}
cs

4. Board 테이블과 연동하는 메소드를 소유한 BoardDao 클래스를 생성하고 메소드 작성 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package dao;
import domain.Board;
public class BoardDao {
public Board get(int num) {
 
        Board board = new Board();
        board.setNum(num);
        board.setId("dispo0");
        board.setName("관리자");
        board.setSubject("공지사항");
        board.setContent("미세먼지 조심하세요 ");
        board.setReadcount(1);
        board.setWritedate("2018-04-07");
        return board;
}
 
}
cs

5.실제 비지니스 로직의 메소드 원형을 소유한 Service 인터페이스 생성

=>service.BoardService

1
2
3
4
5
6
package service;
import domain.Board;
 
public interface BoardService {
    public Board get(int num);
}
cs

6.비지니스 로직을 구현할 ServiceImpl 클래스를 생성하고 메소드 구현

=>service.BoardServiceImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package service;
 
import dao.BoardDao;
import domain.Board;
 
public class BoardServiceImpl implements BoardService {
    //BoardDao 참조형 변수
    private BoardDao boardDao;
    
    //접근자 메소드
    public BoardDao getBoardDao() {
        return boardDao;
}
 
    public void setBoardDao(BoardDao boardDao) {
        this.boardDao = boardDao;
    }
    
    //비지니스 로직을 수행하는 메소드
    @Override
    public Board get(int num) {
        return boardDao.get(num);
    }
}
cs

7.클라이언트의 요청을 받아서 적절한 비지니스 로직 처리 메소드를 호출하는 Controller를 생성하고 메소드 작성 

=>controller.BoardController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package controller;
 
import domain.Board;
import service.BoardService;
public class Controller {
private BoardService boardService;
 
    public BoardService getBoardService() {
        return boardService;
}
 
    public void setBoardService(BoardService boardService) {
        this.boardService = boardService;
}
 
    public Board doGet(int num) {
return boardService.get(num);
 
    }
}
cs

8.main 메소드를 소유한 Main 클래스를 만들어서 실행 코드를 작성하고 실

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
import controller.BoardController;
import dao.BoardDao;
import domain.Board;
import service.BoardServiceImpl;
public class Main {
 
    public static void main(String[] args) {
        //BoardDao 객체 생성
        BoardDao boardDao = new BoardDao();
        
        //BoardService 객체 생성
        BoardServiceImpl boardService = 
            new BoardServiceImpl();
        //BoardDao 객체 주입
        boardService.setBoardDao(boardDao);
        
        //BoardController 객체 생성
        BoardController boardController = 
            new BoardController();
        //BoardService 객체 주입
        boardController.setBoardService(boardService);
        
        Board board = boardController.doGet(101);
        
        System.out.println(board);
}
 
}
cs

9.객체를 singleton으로 생성할 수 있도록 해주는 설정 파일을 추가

src/main/resources 디렉토리에 applicationContext.xml

1
2
3
4
5
6
7
8
9
10
11
12
<?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="boardDao" class="dao.BoardDao"></bean>
    
    <bean id="boardService" class="service.BoardServiceImpl"></bean>
<bean id="boardController" class="controller.BoardController"></bean>
 
 
</beans>
cs

10.main 메소드를 수정하고 실행

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
package main;
import org.springframework.context.support.GenericXmlApplicationContext;
 
import controller.Controller;
import dao.BoardDao;
import domain.Board;
import service.BoardServiceImpl;
public class Main {
public static void main(String[] args) {
 
        
        GenericXmlApplicationContext context = new GenericXmlApplicationContext("classpath:applicationContext.xml");
        
        
        
        // BoardDao 객체 생성
BoardDao boardDao = context.getBean(BoardDao.class);
 
        // BoardSerivce 객체 생성
BoardServiceImpl boardservice = context.getBean(BoardServiceImpl.class);
 
        // BoardDao 객체 주입
boardservice.setBoardDao(boardDao);
 
        // 컨트롤 객체 생성
Controller boardController = context.getBean(Controller.class);
 
        // boardService 객체 주입
boardController.setBoardService(boardservice);
Board board = boardController.doGet(101);
 
        System.out.println(board);
}
 
}
cs

11. IOC만 적용한 경우 

=>Spring의 Ioc를 적용하면 Spring이 생성하는 객체는 전부 Singleton 패턴으로 만들어지고 실행할 때 객체를 모두 생성해서 사용가능하도록 해줍니다. 

context.close하면 메모지 정리를 전부다 해줍니다. 

12.applicationContext.xml 파일에 property를 이용해서 BoardService 객체에는 Boardao 객체를 BoardContoller 객체에는 BoardService 객체를 

주입하는 코드를 작성 -DI 적용 

1
2
3
4
5
6
7
8
<bean id="boardDao" class="dao.BoardDao">
    </bean>
    <bean id="boardService" class="service.BoardServiceImpl">
        <property name="boardDao" ref="boardDao"></property>
    </bean>
    <bean id="boardContoller" class="controller.Controller">
        <property name="boardService" ref="boardService"></property>
    </bean>
cs

13.main 메소드를 수정하고 실행

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String[] args) {
 
        
        GenericXmlApplicationContext context = 
                new GenericXmlApplicationContext(
                        "classpath:applicationContext.xml");
        // 컨트롤 객체 생성
Controller boardController = context.getBean(Controller.class);
 
        Board board = boardController.doGet(101);
        System.out.println(board);
    
    
        context.close();
    }
cs

14.Spring DI를 이용하면 실해앟고자 하는 크랠스의 객체만 만들어서 필요한 메소드를 호출하기만 하면됩니ㅏㄷ. 

중간에 대입하고 하는 과정응ㄴ 새략해도 됩니다. 

**annotation과 xml 의 혼용 

=>spring bean configuration 파일에 context 네임스페이스를 추가하고 

<context:annotation-config>태그를 추가해야 합니다.


@Autowired

=>인스턴스 변수 위에 어노테이션을 추가하면 setter를 자동생성해주고 동일한 자료형의 bean이 있으면 자동으로 대입해줍니다. 

=> 동일한 자료형이 없으면 , 동일한 자료형이 두개 있으면 어떻게 되느냐 ?

자료형이 없으면, 주입할 수 없다 

동일한 자료형이 두개 있으면 연결불가능 qualifying bean of type 

2.BoardServiceImpl 클래스에 있는 BoardDao 참조형 변수 위에 @Autowired를 추가하고 접근자 메소드를 제거

3.BoardController 클래스에 있는 BoardService 참조형 변수 위에 @Autowired를 추가하고 접근자 메소드를 제거

4.applicationContext.xml 파일에 context 네임스페이스 추가

5.applicationContext.xml 파일에 <context:annotation-config/> 추가

6.property를 이용한 di 코드를 제거

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
    
    <!-- annotation을 적용하기 위한 태그 -->
<context:annotation-config />
 
    <bean id="boardDao" class="dao.BoardDao"></bean>
    
    <bean id="boardService" class="service.BoardServiceImpl">
    </bean>
    
    <bean id="boardController" class="controller.BoardController">
</bean>
 
</beans>
cs

7. @Autowired 사용시 주의 할점 

1) AutoWired가 설정된 참조형 변수의 bean이 없는 경우 

NoSuch로 시작하는 예외가 발생 

2) 동일한 자료형으로 2개 이상 만들어진 경우 : NoUnique로 시작하는 예외가 발생하는데 

이 문제를 해결하는 방법으로는 @Autowired 아래에 @Qualifier ("빈의 아이디")를 추가 하면됩니다. 

8. Autowired 대신에 Resource(name="빈의 아이디")를 사용할 수 있고 inject 라이브러리를 추가하면 

@inject를 사용할 수 있습니다. 

bean 자동 생성

=>spring bean configuration 파일에 <context:component-scan base-package="패키지이름"/> 태그가 존재하면 패키지이름 하위에 존재하는 클래스 들 중에서 @Component, @Controller, @Service, @Repository 어노테이션이 있는 클래스들의 bean을 자동 생성해 줍니다.

=>@Component는 모든 클래스에 추가가 가능한데 Controller, Service, Repository는 역할에 맞게 추가해야 합니다.

=>id는 클래스이름의 첫글자만 소문자로 변경한 것으로 자동 설정됩니다.

1.controller, service, dao 패키지 안에 있는 클래스들을 board 패키지를 생성해서 안으로 전부 이동

2.BoardDao, BoardServiceImpl, BoardController 클래스 위에 @Component 어노테이션을 추가

3.applicationContext.xml 파일에 3개의 클래스 bean 태그를 제거

4.applicationContext.xml 파일에 @Component가 붙은 클래스들의 bean을 자동생성해주는 태그를 추가

<!-- board 패키지에 있는 클래스들 중에서

@Component(Controller, Service, Repository)가 붙은

클래스들의 bean을 자동 생성 -->

<context:component-scan base-package="board" />

====================================

=> set 메소드를 이용해서 인스턴스 변수에 데이터를 대입 

=> 생성자를 이용하는 것보다 느리게 만들어지지만 메모리 부담은 줄어듭니다. 

python과 C#에서는 변수.변수명 으로 불러서 프로퍼리를 할수 있게 해줍니다. 

<bean id="빈의 아이디" class="클래스의 경로">

<property name="프로퍼리이름" value="값"> </property>

<property name="프로퍼티이름" ref="다른 bean의 아이디"></property>

</bean>

=>프로퍼티이름은 변수명이 아니며, setter 메소드에서 set을 제외하고 나머지 문자열의 

첫글자만 소문자로 변경합니다. 

=>MemberVo 는 2개의 프로퍼티가 존재합니다. 

1. applicationContext.xml 파일에 property에 의존성 주입하는 bean을 생성하는 코드를 작성 

1
2
3
4
5
6
7
8
9
<bean id = "memberVo4" class="domain.MemberVo">
<property name="email" value="tstigma@naver.com"></property>
<property name="name" ref="second"></property>
</bean>
 
<bean id = "second" class="java.lang.String">
<constructor-arg value="armor"></constructor-arg>
</bean>
 
cs

2.main 메소드에서 bean을 가져오는 코드를 작성하고 실행 

1
2
MemberVo memberVo4 = context.getBean("memberVo4",MemberVo.class);
System.out.println(memberVo4);
cs

======================================================

namespace

======================================================

**namespace(이름공간)를 이용하면 constructor-arg 나 property태그 대신에 bean을 생성하는 코드 내부에 속성으로 값을 대입할 수 있습니다. 

c와 p네임스페이스를 추가하면 됩니다. 

코드를 간결하게 만들기 위해 사용합니다. 

1.applicationContext.xml 파일에 c와 p 네임스페이스 추가

2.applicationContext.xml 파일에 c와 p 네임스페이스를 이용한 bean 생성 코드 추가

1
2
3
4
5
6
7
8
9
10
<!-- MemberVO memberVO4 = 
        new MemberVO("abc@gmail.com""조헌"); -->
    <bean id="memberVO4" class="domain.MemberVO"
    c:email="abc@gmail.com" c:name="조헌"/>
    
    <!-- MemberVO memberVO5 = new MemberVO(); 
    memberVO5.setEmail("efg@gmail.com");
    memberVO5.setName("강감찬")-->
    <bean id="memberVO5" class="domain.MemberVO"
    p:email="efg@gmail.com" p:name="강감찬" />
cs

=======================================================

Collection을 주입받기 위한 예제 

1. 4개의 Collection을 인스턴스 변수로 갖는 클래스 생성 

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
domain.CollectionDI
package domain;
 
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class CollectionDI {
// 4개의 Collection인스턴스 변수
 
    private List<String> list;
    private Set<String> set;
    private Properties properties;
private Map<String, Object> map;
 
    public List<String> getList() {
        return list;
}
 
    public void setList(List<String> list) {
        this.list = list;
}
 
    public Set<String> getSet() {
        return set;
}
 
    public void setSet(Set<String> set) {
        this.set = set;
}
 
    public Properties getProperties() {
        return properties;
}
 
    public void setProperties(Properties properties) {
        this.properties = properties;
}
 
    public Map<String, Object> getMap() {
        return map;
}
 
    public void setMap(Map<String, Object> map) {
        this.map = map;
}
 
    @Override
    public String toString() {
        return "CollectionDI [list=" + list + ", set=" + set + ", properties=" + properties + ", map=" + map + "]";
}
 
}
cs

2.SpringBeanConfiguration 파일을 생성하고 CollectionDI 객체를 생성해주는 bean 코드를 추가

=>src/main/resources 디렉토리의 collection.xml

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
<?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="collectionDI" class="domain.CollectionDI">
        <property name="list">
            <list>
                <value>배열</value>
                <value>ArrayList</value>
                <value>LinkedList</value>
                <value>Stack</value>
                <value>Queue</value>
                <value>Deque</value>
            </list>
        </property>
        
        <property name="set">
            <set>
                <value>HashSet</value>
                <value>LinkedHashSet</value>
                <value>TreeSet</value>
            </set>
        </property>
        
        <property name="properties">
            <props>
                <prop key="Encapsulation">캡슐화</prop>
                <prop key="Inheritance">상속성</prop>
                <prop key="Polymorphism">다형성</prop>
            </props>
        </property>
        
        <property name="map">
            <map>
                <entry>
                    <key><value>Encapsulation</value></key>
                    <value>클래스를 만드는 것</value>
                </entry>
                <entry>
                    <key><value>Inheritance</value></key>
                    <value>하위 클래스가 상위 클래스의 모든 것을
                    물려받는 것</value>
                </entry>
                <entry>
                    <key><value>Polymorphism</value></key>
                    <value>동일한 메시지에 대하여 다르게
                    반응하는 성질</value>
                </entry>
            </map>
        </property>
</bean>
 
</beans>
cs

**일반적인 프로그램 구조 

domain class, DAO---> Service ----> Controller --- > View

=>ApplicationProgramming 에서는 Controller의 역할을 Main이 합니다. 

1. spring과 java version 바꿉니다. 

2. Spring과 Java 버전 설정 

3. VO로 사용할 클래스 생성 

package domain;

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
public class Board {
 
    
    private int num ; 
    private String id;
    private String name;
    private String subject;
    private String content;
    private int readcount; 
    private String writedate ; //작성일 ㅁ
    public int getNum() {
        return num;
    }
    public void setNum(int num) {
        this.num = num;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSubject() {
        return subject;
    }
    public void setSubject(String subject) {
        this.subject = subject;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public int getReadcount() {
        return readcount;
    }
    public void setReadcount(int readcount) {
        this.readcount = readcount;
    }
    public String getWritedate() {
        return writedate;
    }
    public void setWritedate(String writedate) {
        this.writedate = writedate;
    }
    
    
    @Override
    public String toString() {
        return "Board [num=" + num + ", id=" + id + ", name=" + name + ", subject=" + subject + ", content=" + content
                + ", readcount=" + readcount + ", writedate=" + writedate + "]";
    }
    
}
cs

4. Board 테이블과 연동하는 메소드를 소유한 BoardDao 클래스를 생성하고 메소드 작성 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package dao;
import domain.Board;
public class BoardDao {
public Board get(int num) {
 
        Board board = new Board();
        board.setNum(num);
        board.setId("dispo0");
        board.setName("관리자");
        board.setSubject("공지사항");
        board.setContent("미세먼지 조심하세요 ");
        board.setReadcount(1);
        board.setWritedate("2018-04-07");
        return board;
}
 
}
cs

5.실제 비지니스 로직의 메소드 원형을 소유한 Service 인터페이스 생성

=>service.BoardService

1
2
3
4
5
6
package service;
import domain.Board;
 
public interface BoardService {
    public Board get(int num);
}
cs

6.비지니스 로직을 구현할 ServiceImpl 클래스를 생성하고 메소드 구현

=>service.BoardServiceImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package service;
 
import dao.BoardDao;
import domain.Board;
 
public class BoardServiceImpl implements BoardService {
    //BoardDao 참조형 변수
    private BoardDao boardDao;
    
    //접근자 메소드
    public BoardDao getBoardDao() {
        return boardDao;
}
 
    public void setBoardDao(BoardDao boardDao) {
        this.boardDao = boardDao;
    }
    
    //비지니스 로직을 수행하는 메소드
    @Override
    public Board get(int num) {
        return boardDao.get(num);
    }
}
cs

7.클라이언트의 요청을 받아서 적절한 비지니스 로직 처리 메소드를 호출하는 Controller를 생성하고 메소드 작성 

=>controller.BoardController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package controller;
 
import domain.Board;
import service.BoardService;
public class Controller {
private BoardService boardService;
 
    public BoardService getBoardService() {
        return boardService;
}
 
    public void setBoardService(BoardService boardService) {
        this.boardService = boardService;
}
 
    public Board doGet(int num) {
return boardService.get(num);
 
    }
}
cs

8.main 메소드를 소유한 Main 클래스를 만들어서 실행 코드를 작성하고 실

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
import controller.BoardController;
import dao.BoardDao;
import domain.Board;
import service.BoardServiceImpl;
public class Main {
 
    public static void main(String[] args) {
        //BoardDao 객체 생성
        BoardDao boardDao = new BoardDao();
        
        //BoardService 객체 생성
        BoardServiceImpl boardService = 
            new BoardServiceImpl();
        //BoardDao 객체 주입
        boardService.setBoardDao(boardDao);
        
        //BoardController 객체 생성
        BoardController boardController = 
            new BoardController();
        //BoardService 객체 주입
        boardController.setBoardService(boardService);
        
        Board board = boardController.doGet(101);
        
        System.out.println(board);
}
 
}
cs

9.객체를 singleton으로 생성할 수 있도록 해주는 설정 파일을 추가

src/main/resources 디렉토리에 applicationContext.xml

1
2
3
4
5
6
7
8
9
10
11
12
<?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="boardDao" class="dao.BoardDao"></bean>
    
    <bean id="boardService" class="service.BoardServiceImpl"></bean>
<bean id="boardController" class="controller.BoardController"></bean>
 
 
</beans>
cs

10.main 메소드를 수정하고 실행

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
package main;
import org.springframework.context.support.GenericXmlApplicationContext;
 
import controller.Controller;
import dao.BoardDao;
import domain.Board;
import service.BoardServiceImpl;
public class Main {
public static void main(String[] args) {
 
        
        GenericXmlApplicationContext context = new GenericXmlApplicationContext("classpath:applicationContext.xml");
        
        
        
        // BoardDao 객체 생성
BoardDao boardDao = context.getBean(BoardDao.class);
 
        // BoardSerivce 객체 생성
BoardServiceImpl boardservice = context.getBean(BoardServiceImpl.class);
 
        // BoardDao 객체 주입
boardservice.setBoardDao(boardDao);
 
        // 컨트롤 객체 생성
Controller boardController = context.getBean(Controller.class);
 
        // boardService 객체 주입
boardController.setBoardService(boardservice);
Board board = boardController.doGet(101);
 
        System.out.println(board);
}
 
}
cs

11. IOC만 적용한 경우 

=>Spring의 Ioc를 적용하면 Spring이 생성하는 객체는 전부 Singleton 패턴으로 만들어지고 실행할 때 객체를 모두 생성해서 사용가능하도록 해줍니다. 


context.close하면 메모지 정리를 전부다 해줍니다.

12.applicationContext.xml 파일에 property를 이용해서 BoardService 객체에는 Boardao 객체를 BoardContoller 객체에는 BoardService 객체를 주입하는 코드를 작성 -DI 적용 

1
2
3
4
5
6
7
8
<bean id="boardDao" class="dao.BoardDao">
    </bean>
    <bean id="boardService" class="service.BoardServiceImpl">
        <property name="boardDao" ref="boardDao"></property>
    </bean>
    <bean id="boardContoller" class="controller.Controller">
        <property name="boardService" ref="boardService"></property>
</bean>
cs

13.main 메소드를 수정하고 실행

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String[] args) {
 
        
        GenericXmlApplicationContext context = 
                new GenericXmlApplicationContext(
                        "classpath:applicationContext.xml");
        // 컨트롤 객체 생성
Controller boardController = context.getBean(Controller.class);
 
        Board board = boardController.doGet(101);
        System.out.println(board);
    
    
        context.close();
    }
cs

14.Spring DI를 이용하면 실해앟고자 하는 크랠스의 객체만 만들어서 필요한 메소드를 호출하기만 하면됩니ㅏㄷ. 

중간에 대입하고 하는 과정응ㄴ 새략해도 됩니다. 

**annotation과 xml 의 혼용 

=>spring bean configuration 파일에 context 네임스페이스를 추가하고 

<context:annotation-config>태그를 추가해야 합니다.

1. @Autowired

=>인스턴스 변수 위에 어노테이션을 추가하면 setter를 자동생성해주고 동일한 자료형의 bean이 있으면 자동으로 대입해줍니다. 

=> 동일한 자료형이 없으면 , 동일한 자료형이 두개 있으면 어떻게 되느냐 ?

자료형이 없으면, 주입할 수 없다 

동일한 자료형이 두개 있으면 연결불가능 qualifying bean of type 

2.BoardServiceImpl 클래스에 있는 BoardDao 참조형 변수 위에 @Autowired를 추가하고 접근자 메소드를 제거

3.BoardController 클래스에 있는 BoardService 참조형 변수 위에 @Autowired를 추가하고 접근자 메소드를 제거

4.applicationContext.xml 파일에 context 네임스페이스 추가

5.applicationContext.xml 파일에 <context:annotation-config/> 추가

6.property를 이용한 di 코드를 제거

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
    
    <!-- annotation을 적용하기 위한 태그 -->
<context:annotation-config />
 
    <bean id="boardDao" class="dao.BoardDao"></bean>
    
    <bean id="boardService" class="service.BoardServiceImpl">
    </bean>
    
    <bean id="boardController" class="controller.BoardController">
</bean>
 
</beans>
cs

7. @Autowired 사용시 주의 할점 

1) AutoWired가 설정된 참조형 변수의 bean이 없는 경우 

NoSuch로 시작하는 예외가 발생 

2) 동일한 자료형으로 2개 이상 만들어진 경우 : NoUnique로 시작하는 예외가 발생하는데 

이 문제를 해결하는 방법으로는 @Autowired 아래에 @Qualifier ("빈의 아이디")를 추가 하면됩니다. 

8. Autowired 대신에 Resource(name="빈의 아이디")를 사용할 수 있고 inject 라이브러리를 추가하면 

@inject를 사용할 수 있습니다. 

**bean 자동 생성

=>spring bean configuration 파일에 <context:component-scan base-package="패키지이름"/> 태그가 존재하면 패키지이름 하위에 존재하는 클래스 들 중에서 @Component, @Controller, @Service, @Repository 어노테이션이 있는 클래스들의 bean을 자동 생성해 줍니다.

=>@Component는 모든 클래스에 추가가 가능한데 Controller, Service, Repository는 역할에 맞게 추가해야 합니다.

=>id는 클래스이름의 첫글자만 소문자로 변경한 것으로 자동 설정됩니다.

1.controller, service, dao 패키지 안에 있는 클래스들을 board 패키지를 생성해서 안으로 전부 이동

2.BoardDao, BoardServiceImpl, BoardController 클래스 위에 @Component 어노테이션을 추가

3.applicationContext.xml 파일에 3개의 클래스 bean 태그를 제거

4.applicationContext.xml 파일에 @Component가 붙은 클래스들의 bean을 자동생성해주는 태그를 추가

<!-- board 패키지에 있는 클래스들 중에서

@Component(Controller, Service, Repository)가 붙은

클래스들의 bean을 자동 생성 -->

<context:component-scan base-package="board" />

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

Spring 2-2 TEST 디렉토리 사용  (0) 2018.04.09
Spring 2-1 Property(속성)  (0) 2018.04.09
DI(Dependency Injection)  (0) 2018.04.05
Spring 1-1) IOC 제어의 역전  (0) 2018.04.05
1. Spring의 정의와 특징  (0) 2018.04.05

DI(Dependency Injection) 




의존성: 클래스 사이의 관계 – has a(포함 관계)

주입: 의존하는 변수의 값을 설정하는 방법

객체지향 프로그래밍언어에서는 의존하는 변수의 값을 설정할 때(의존관계 설정) 

생성자나 setter 메소드를 호출해서 하지만 스프링에서는 이를 beanfactory를 이용해서 설정합니다. 



1) is a : 상속관계                     

2) has a : 포함관계 - 어느 하나의 클래스가 다른 클래스 안에서 사용되는 것 



[DTO]

private int x는 vo라고 한다. 

getter& setter 프로퍼티를 이용한 주입 


2. 의존성 주입 

=> has a  관계에서 포함된 클래스의 객체를 어떻게 대입하느냐 하는 문제 

=> 방법은 객체가 생성될 때 생성자를 이용해서 대입하는 방법이 있고 

  다른 하나는 필요할 때 프로퍼티(setter)를 이용해서 대입하는 방법이 있습니다. 

  

3. 생성자를 이용하는 경우 


<bean id = "" class=""> 

<constructor-arg value=""></constructor-arg>

<bean> 


생성자의 매개변수가 여러 개면 여러 번 반복해서 대입이 가능합니다. 

=> 값이 아니고 다른 bean을 대입하고자 하는 경우에는 <ref bean="빈의 아이디"></ref>


 4. Good 클래스의 객체를 생성해주는 bean 코드를 applicationContext.xml 파일에 생성 

 

 5. applicationContext.xml 파일에 만든 good 이라는 id를 가진 Good 클래스의 객체를 사용하는 코드를 Main 클래스의 main메소드에 작성 

 

 

 Constructor(생성자) 



 =>클래스를 가지고 객체를 생성할 때 호출하는 메소드 

 => new 생성자(매개변수) 의 형태로만 호출할 수 있습니다. 

 => 생성자는 클래스 이름과 동이랗게 만들어야 합니다. 

 => 클래스를 만들면 눈에 보이지는 않지만 매개변수가 없는 생성자가 자동으로 만들어집니다. Default Constructor(매개변수가 없는 생성자)

 => Good 클래스의 경우는 이런 생성자가 숨겨져있습니다. 

 public Good(){

 super() 상위 클래스의 생성자를 호출하는 구문 

 }

 

=>생성자를 직접 만들면 제공되는 생성자는 소멸됩니다. 

=> 생성자는 오버로딩  ( 이름은 같고 매개변수의 개수나 자료형이 다른 경우 ) 가능합니다. 

=> 생성자를 만드는 이유는 객체를 생성할 때 매개변수를 받아서 인스턴변수를 초기화 할 의도나 

객체를 생성할 때, 바로 수행되어야할 내용이 있을 때 사용합니다.

1. Good 클래스에 code 넘겨받아서 code를 설정하는 생성자를 추가 

=> 실행하면 에러가 발생합니다. 

=> 생성자를 만들게 되면 매개변수가 없는 생성자가 제거되고 spring은 별도의 설정이 없으면 매개 변수가 없는 생성자를 

호출해서 객체를 만들기 때문입니다. 


1
2
3
4
5
6
7
//public  Good(String code) {
 
    this.code = code; 
 
}
 
 
cs



2.applicationContext.xml 파일의 Good 객체를 생성할 때 생성자에게 데이터를 넘겨서 매개변수가 있는 생성자를 호출하도록

해주어야합니다. 

1
2
3
4
5
6
7
//이러한 방법은 생성자의 의존성 주입이라고 합니다. 
 
<bean id="good" class="domain.Good">
 
    <constructor-arg value="010"></constructor-arg>
 
</bean>
cs


3. 2번의 코드를 변경 

=> 2번의 코드는 값을 직접 입력한 경우이고 이번의 코드는 다른 빈을 참조하는 코드 

<!-- new String("")을 이용해서 마든 문자열 객체-->
<bean id="code" class="java.lang.String">
<constructor-arg value="232"/>
</bean>
<!-- code라는 bean을 생성자의 첫번째 매개변수로 대입해서 생성한 Good 클래스의 객체 -->
<bean id="good" class="domain.Good">
//ref : 다른 애를 참조한다
<constructor-arg ref="code"></constructor-arg>
</bean>


'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
Spring 1-1) IOC 제어의 역전  (0) 2018.04.05
1. Spring의 정의와 특징  (0) 2018.04.05

**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

스프링 





스프링이란 무엇인가 ? 

자바 엔터프라이즈 개발을 편하게 해주는 오픈 소스로 경량급 Application 프레임워크입니다. 



스프링의 특징 

=> 가장 강력한 자바 오픈소스 프레임워크 
=> J2EE가 가진 거의 모든 기능을 소유한 프레임워크 

ü복잡함에 반기를 들어서 나온 프레임워크
ü플랫폼 호환성 문제 해결
ü스프링은 JavaEE가 제공하는 다수의 기능을 지원하고 있기 때문에 JavaEE대체
ü스프링은 IoC(제어의 역전) 지원
+> Ioc(제어의 역전) 객체를 내가 만들지 않는 것 클래스 
=> ex ) FIlter, Controller 
ü스프링은 DI(Dependency Injection)패턴을 지원
=> DI : 의존성 주입  Maven의 Pom.xml 

ü스프링은 AOP(Aspect Oriented Programming)지원
=> AOP :  관점 지향프로그래밍 관점에 따라 나누어 작업하자 
ü스프링은 POJO(Plain Old Java Object)지원

=> POJO는 MVC 패턴을 적용한 프로젝트에서 DAO, VO, SERVICE  순순한 자바로부터 상속, 
=> POJO가 아닌 애는 HTTPServlet을 상속받은 Controller가됩니다.  

ü트랜잭션 처리를 위한 일관된 방법을 제공
ü영속성 - MyBatis, Hibernate, JPA등과 같은 프레임워크와의 연동을 지원
ü편리한 MVC 구조를 가지고 있고 WAS에 종속되지 않는 개발 환경
ü2.5버전에서 어노테이션을 이용한 설정 지원
ü3.0에서는 Java 클래스를 이용한 설정 지원
ü4.0에서는 REST 방식의 Controller 지원


v스프링 프로젝트 종류

üSpring Boot를 이용(Spring Starter Project): 최대한 간단하게 실행하고 배포가 가능한 수준의 애플리케이션을 만들 때 사용하는데 WAS 설정없이 실행이 가능하기 때문에 테스트 하기에 편리하지만 기존의 웹 프로젝트 설정과 다른 방법으로 사용하며 JSP 설정은 별도로 수행 <작은 프로젝트에서 사용>

üSpring Template Project 이용(Spring Legacy Project): WAS를 사용하거나 이전에 Spring Project를 만들어본 경우 사용하는 방식인데 WAS로 인한 리소스 소모가 심하다는 단점이 있지만 기존 프로젝트들이 이 방식으로 많이 만들어져 있음 <큰 프로젝트에서 사용>






'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
Spring 1-1) IOC 제어의 역전  (0) 2018.04.05

+ Recent posts