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

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