IoC(제어의 역전)

  • 클래스는 개발자가 만들고 클래스의 인스턴스는 프레임워크가 WAS가 만들어서 일반적인 프로그래밍의 흐름의 반대로 수행되는 것

1.Factory Method Pattern 실습

image-20200217120359369

image-20200217120602916

image-20200217121056266

image-20200217121123800

1) Temp 클래스 생성

public class Temp {
    private int num;
    private String name;

    public Temp(int num, String name) {
        super();
        this.num = num;
        this.name = name;
    }

    public Temp() {
        super();
        // TODO Auto-generated constructor stub
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Temp [num=" + num + ", name=" + name + "]";
    }
}

3) Main 메소드를 소유한 main 클래스를 만들고 Temp 클래스 사용

public class Main {

    public static void main(String[] args) {
        Temp temp = new Temp();
        temp.setName("Lee");
        temp.setNum(1);
        System.out.println(temp);
    }
}
  • 사용자가 만든 클래스를 가지고 직접 생성자를 호출해서 인스턴스를 만들고 사용

2.Factory Method Pattern

  • 클래스의 인스턴스를 new를 직접 호출해서 생성하지 않고 다른 클래스의 메소드를 이용해서 생성하는 방식
  • 만드는 과정이 복잡하거나 디자인 패턴이나 기타코드를 클래스에 추가하고자 하는 경우 사용

3.실습

1) Factory 클래스로 사용할 클래스를 추가

  • TempFactory 클래스
// Temp 클래스의 Factory 클래스 
public class TempFactory {
    // Temp 의 Factory 메소드
    public static Temp create() {
        return new Temp();
    }
}

2) Main 클래스 메소드 수정

public class Main {

    public static void main(String[] args) {
        Temp temp = TempFactory.create();
        temp.setName("Lee");
        temp.setNum(1);
        System.out.println(temp);
    }
}

클래스는 내가 만들었지만 실제 클래스는 Factory 클래스가 만들어주고, 실제쓰는것은 Factory 클래스에서 주는걸 쓴다.

4.Singleton 패턴

  • 어떤 클래스가 인스턴스를 1개만 만들수 있도록 된 디자인 패턴
  • 서버 쪽의 클래스들은 대부분의 경우 여러개의 인스턴스를 만들지 않고 하나의 인스턴스가 스레드를 이용해서 클라이언트 들의 요청을 처리하도록 해야 하는 경우가 대부분이고

메소드(함수) : Server는 20줄 이하로
변수 -> 함수 -> 클래스,객체
클래스, 객체 지향은 무겁지만. 안정성이 높다. .
함수만는 객체지향보다는 가볍지만 안정성이 낮다.

한개만 만들어서 공유 한다 - static

Spring java application project 생성

1. project 생성

  • [file] - [new] - [other] - [spring legacy project] 를 선택하고 [simple spring maven]

2.디렉토리가 생성되지 않은 경우

1) maven 프로젝트로 변환

  • 프로젝트를 선택하고 마우스 오른쪽을 누른 후 [configure] - [convert to maven project]

2) pom.xml 파일에 붙여 넣기

<!-- 이 코드를 pom.xml 파일에 붙여 넣습니다 -->
<!-- 자주 사용하는 코드를 프로퍼티로 설정해놓은 태그  -->
<!-- 프로그램에서 변수를 만드는 것과 유사  -->
<!-- 자주 사용하는 버전들의 이름을 변수로 등록해 두는 것이 Properties 입니다. -->
  <properties>
        <!-- 자바 버전  -->
        <java.version>1.6</java.version>

        <!-- 소스코드와 출력되는 문자열을 인코딩 설정  -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

        <!-- Spring 버전 4.0.1, 5.0.7 버전 변경  -->
        <spring-framework.version>5.0.7.RELEASE</spring-framework.version>

        <!-- Hibernate / JPA 버전 -->
        <hibernate.version>4.2.1.Final</hibernate.version>

        <!-- Log 라이브러리 버전  -->
        <logback.version>1.0.13</logback.version>
        <slf4j.version>1.7.5</slf4j.version>

        <!-- Test 라이브러리 버전 (여긴 변경 최근 4.12) -->
        <junit.version>4.12</junit.version>
    </properties>

    <!-- 중앙 저장소 이외에서 다운로드 받아야 할 때 설정: 다운로드 받는 서버를 설정 -->    
    <!--  의존성 라이브러리 설정 -->
    <dependencies>
        <!-- Spring 기본 라이브러리  -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>
    <!-- Sprng 트랜잭션 처리 라이브러리 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>

        <!-- Logg 기록 라이브러리 설정  -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
            <scope>compile</scope>
        </dependency>

    <!-- 런타임이 실행일때 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
            <scope>runtime</scope>
        </dependency>

        <!-- Hibernate -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate.version}</version>
        </dependency>

        <!-- 스프링 테스트 - Test 할 때만 존재하고 배포할때는 자동으로 없어진다. -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring-framework.version}</version>
            <scope>test</scope>
    </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>    
</project>

3) 속성을 2개 갖는 클래스를 생성

  • 디렉토리가 만들어진 경우에는 src/main/java 라는 디렉토리에 생성하고 그렇지 않은 경우는 root 디렉토리에 생성
  • 디렉토리가 없는 경우는 프로젝트를 생성
public class Item {

    private int num;
    private String name;
    public int getNum() {
        return num;
    }
    public void setNum(int num) {
        this.num = num;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Item [num=" + num + ", name=" + name + "]";
    }
}

Spring 의 Bean Container

  • Spring에서는 Spring이 제어권을 가지고 생성하고 관계를 설정하는 객체를 Spring Bean 이라고 한다.
  • Bean이 Spring이 객체를 생성하고 관리하는 제어의 역전이 적용된 객체
  • Bean Container를 만드는 방법

1.annotation을 이용하는 방법

1) 설정

  • 클래스를 만들고 클래스 위에 @Configuration 어노테이션을 추가
  • 인스턴스를 생성해서 리턴하는 메소드 위에 @Bean 어노테이션을 추가

2) 사용

AnnotationConfigApplicationContext 변수명 = new AnnotationConfigApplicationContext(앞에서만든 클래스이름.class);
인스턴스이름 = 변수명.getBean("메소드이름",메소드가 리턴하는클래스이름.class);
  • 이렇게 만들면 싱글톤을 적용하지 않아도 자동으로 싱글톤 패턴의 객체가 리턴된다.

3) 실습

  • Factory 클래스의 역할을 수행할 클래스를 생성 - Factory 클래스
// Spring의 Bean을 생성해주는 클래스라는 어느테이션 
@Configuration
public class Factory {
    // Bean을 만들어주는 메소드라는 어노테이션 
    // 이 메소드는 매번 Item 인스턴스를 만들어서 리턴하는 것이 아니고 
    // 처음 1개를 만들고 다음부터는 이 메소드를 호출하면 만들어지 것을 리턴 
    @Bean
    public static Item create() {
        return new Item();
    }
}
  • Main 메소드를 소유한 클래스를 만들어서 인스턴스를 만든 후 테스트 - SpringMain 클래스
public class SpringMain {

    public static void main(String[] args) {
        // SpringContainer 클래스 객체 만들기
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Factory.class);
        // Bean 생성 메소드를 호출해서 Bean을 생성
        // Factory 클래스의 create 라는 메소드를 이용해서 인스턴스를 생성하고 리턴
        Item item1 = context.getBean("create", Item.class);
        item1.setNum(1);
        item1.setName("사과");
        System.out.println(item1);
        // item1과 2의 해시코드 출력
        System.out.println(item1.hashCode());

        Item item2 = context.getBean("create", Item.class);
        item2.setNum(2);
        item2.setName("배");
        System.out.println(item2);
        System.out.println(item2.hashCode());
    }
}

item1과 item2의 해시코드가 동일하다
Factory 클래스의 Bean이 붙은 클래스의 메소드는 계속호출되지 않고 맨처음 한번만 호출하고다음부터는 이전에 만들어진 객체를 이용한다

@Configuration
public class Factory {
    //Bean을 만들어주는 메소드라는 어노테이션 
    @Bean
    public static Item create() {
        // Bean이 붙은 클래스의 메소드는 계속호출되지 않고 맨처음 한번만 호출하고다음부터는 이전에 만들어진 객체를 이용한다  
        return new Item();
    }
}
  • main 메소드를 소유한 클래스를 만들어서 인스턴스를 만든 후 테스트

2.XML을 이용하는 방법 : 현재까지는 이 방법을 많이 사용

1) spring bean configuration 파일을 추가

2) 객체를 생성하는 태그를 설정

  • 클래스 경로에 해당하는 객체를 생성해서 리턴 - 싱글톤

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

3) 사용

GenericXmlApplicationContext 변수명 = new GenericXmlApplicationContext(xml 파일 경로);
인스턴스이름 = 변수명.getBean("아이디", 메소드가 리턴하는클래스이름.class);

4) 실습

  • spring bean configuration 파일추가 - applicationcontext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <!--  domain.Item 이라는 클래스의 객체를 만들어주는 태그  -->
    <bean id="item" class="domain.Item"/>
</beans>

image-20200217145906266

  • Xml 이용 - main 클래스 변경
public class SpringMain {

    public static void main(String[] args) {
        //xml을 이용하는 방법
        GenericXmlApplicationContext context = new GenericXmlApplicationContext("classpath:applicationcontext.xml");

        // Bean 생성 메소드를 호출해서 Bean을 생성
        // Factory 클래스의 create 라는 메소드를 이용해서 인스턴스를 생성하고 리턴

        // xml 파일을 이용할 때는 id를 기재 
        Item item1 = context.getBean("item", Item.class);
        item1.setNum(1);
        item1.setName("사과");
        System.out.println(item1);
        // item1과 2의 해시코드 출력
        System.out.println(item1.hashCode());

        Item item2 = context.getBean("item", Item.class);
        item2.setNum(2);
        item2.setName("배");
        System.out.println(item2);
        System.out.println(item2.hashCode());
    }
}

3.bean 태그의 속성

1) class

  • 생성할 인스턴스의 class - 패키지 이름 까지 포함시켜야 한다.

2) id

  • 외부에서 인스턴스를 가져다가 사용하기 위한 이름
  • 생략하면 클래스이름 뒤에 #0을 붙입니다.

3) init

  • method : 인스턴스를 생성할 때 호출되는 메소드

4) destroy

  • method : 인스턴스가 소멸될 때 호출되는 메소드

5) lazy-init(지연생성)

  • true를 설정하면 처음부터 만들어지지 않고 처음 사용할 때 만들어진다.
  • 클라이언트 프로그램을 제작할 때 사용
  • lazy-init이 false 이면 프로그램이 실행될 때 전부 만들어두고 실행

6) scope

  • web에서만 설정하는 것으로 기본은 singleton이고 호출할 때 마다 생성하는 prototype 이나 request, session 등의 scope를 설정하는 것이 가능

results matching ""

    No results matching ""