40
Spring Framework & MyBatis 스스스 스스스스스 & 스스스스스 스스 스스스스스 스스스스

NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

  • Upload
    3-2

  • View
    26

  • Download
    7

Embed Size (px)

Citation preview

Page 1: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

Spring Framework & MyBatis스프링 프레임워크 & 마이바티스 강의

탑크리에듀 교육센터

Page 2: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

1. 스프링 프레임워크 개요

2. Spring IoC & DI

2.1 Ioc Container

2.1.1 Ioc Container

2.1.2 Bean Factory, Application Context

2.1.3 Lzay-Loading, Pre-Loading

CONTENTS1. 스프링 프레임워크 개요

2. Spring IoC & DI

2.2 Spring Ioc 실습 (XML 기반 , 인터페이스 , 세터주입 )

2.3 Spring Ioc 실습 ( 어노테이션기반 , 인터페이스 ,

세터주입 )

2.4 DI 와 관련된 어노테이션

2.4.1 Auto-Scanning Component (Stereotyping Annotations),

@Component,

@Repository, @Service, @Controller, @Rest Controller

2.4.2 Context Configuration Annotations (@Scope, @Autowired,

@Resource,

@Inject, @Required, @Named, @Order, @Post

Construct ,@PreDestroy)

Page 3: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

Chapter 2 Spring IoC & DI

~2-4

Page 4: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

마틴 파울러는 2004 년의 글에서 제어의 어떤 측면이 역행되는 것인지에 대한 의문을 제기하고 의존하는 객체를 역행적으로 취득하는 것이라는 결론을 내렸다 . 그는 그와 같은 정의에 기초하여 제어 역행이라는 용어에 좀더 참신한 ‘의존성 주입 (DI, dependency injection)’ 이라는 이름을 지어줬다 .

 

모든 어플리케이션은 비즈니스 로직을 수행하기 위해 서로 협업하는 둘 또는 그 이상의 클래스들로 이뤄진다 . 전통적으로 각 객체는 협업할 객체의 참조를 취득해야 하는 책임이 있다 . 이것이 의존성이다 . 이는 결합도가 높으며 테스트하기 어려운 코드를 만들어 낸다 .

IoC 를 적용함으로써 객체들은 시스템 내의 각 객체를 조정하는 어떤 외부의 존재에 의해 생성 시점에서 의존성을 부여 받는데 , 의존성이 객체로 주입 (inject) 된다는 말이다 . 따라서 IoC 는 한 객체가 협업해야 하는 다른 객체의 참조를 취득하는 방법에 대한 제어의 역행이라는 의미를 갖는다 .

 

일반적으로 IoC 는 의존성주입 (DI), 의존성 룩업 (DL) 두 개의 하위부류로 나눌 수 있으며 일반적으로 DI 를 이야기 할 때는 IoC 를 가리키지만 IoC 를 이야기 할 때는 DI 를 가리키는 것은 아니다 . DI 도 여러 종류 ( 세터주입 , 생성자 주입 , 메소드 주입 ) 가 있지만 DL 의 경우도 의존성 풀과 컨텍스트화 된 의존성 룩업 (CDL) 두 종류가 있다 .

Page 5: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

2-1. Ioc Container

2-1-1. Ioc Container 분류

DL(Dependency Lookup) 

모든 IoC 컨테이너는 각 컨테이너에서 관리해야 하는 객체들을 관리하기 위한 별도의 저장소를 가진다 .Bean 에 접근하기 위하여 컨테이너에서 제공하는 API 를 이용하여 사용하고자 하는 Bean 을 Lookup 하는 것으로 컨테이너 API 와 의존관계를 많이 가지면 가질수록 어플리케이션 컨테이너에 종속되는 단점이 있다 .

Page 6: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

2-1. Ioc Container

2-1-1. Ioc Container 분류 의존성 풀 (Dependency Pull) 

IoC 타입 중 가장 익숙한 타입으로 필요할 때 마다 레지스트리에서 의존성을 가지고 온다 . EJB 의 경우 JNDI API 를 통해 EJB 컴포넌트를 룩업 한다 .

컨텍스트화 된 의존성 룩업(Contextualized Dependency Lookup)

 

컨테이너는 내부 WAS( 톰 캣 , JBOSS 등 )나 스프링 프레임워크에서 제공 한다 .

Page 7: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

2-1. Ioc Container

2-1-1. Ioc Container 분류 Inject vs Lookup  

어떤 IoC 방식을 사용할지는 별로 어렵지 않다 . 스프링의 경우 초기 빈 Lookup 을 제외하면 의존성이 항상 Injection 형태의 IoC 를 사용하게 된다 . 대부분의 환경에서 DI 를 사용해서 모든 객체를 연결할 수는 없으며 초기 컴포넌트에 접근 시 DL 을 사용해야 하는 경우가 많다 . 예를 들어 일반 자바 APP 에서는 main 에서 스프링 컨테이너를 부트스트랩하고 ApplicationContext 인터페이스를 통해 의존객체를 가져와야 한다 . 즉 스프링에서는 DI 를 사용할 수 있으면 사용하고 그렇지 못한 경우라면 DL 을 사용하면 된다 . 

의존성 풀 방식의 코드는 레지스트리에 대한 참조를 가지고 있어야 하고 레지스트리와 연동해서 의존성 객체를 가지고 와야 한다 . 또한 CDL 을 사용시 특정 인터페이스를 구현해야 하고 모든 의존성을 직접 가지고 와야 한다 . 하지만 의존성 주입 (Dependency Injection) 을 사용하면 적절한 생성자 , 메소드 , 세터 등을 통해 의존성을 주입 받기만 하면 된다 .

Page 8: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

2-1. Ioc Container

2-1-2. Bean Factory, Application Context 분류 Bean Factory  

• 스프링의 의존성 주입의 핵심 인터페이스• Bean 의 생성과 소멸 담당 ( 의존성과 생명주기 및 관리 담당 ), 객체를 관리하는 고급 설정 기법 제공• DI 지원 기능만 필요하다면 BeanFactory 인터페이스를 이용해 스프링 DI 컨테이너와 직접 연동할

수 있다 . 이 경우 애플리케이션은 BeanFactory 인터페이스를 구현한 클래스의 인터페이스를 생성하고 이 인스턴스에 빈과 의존성 설정 정보를 저장해야 한다 .

• BeanFactory 를 프로그래밍적으로 설정할 수도 있지만 대부분 설정 파일을 통해 외부에서 설정하는 방식을 사용한다 .

• 스프링에서 기본적으로 제공하는 두 개의 메인 Bean Factory 는 Bean Definition Registry 를 구현하고 있다 . Properties Bean Definition Reader 는 프로퍼티 파일에서 Bean 정의를 읽고 Xml Bean Definition Reader 는 XML 파일에서 Bean 정의를 읽는다 .

Page 9: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

Application Context 

• Bean Factory 의 모든 기능 제공 (Bean Factory 인터페이스를 상속 )• 권장하는 방식으로 스프링 DI 뿐 아니라 트랜잭션 , AOP 서비스 , 국제화를 위한 메시지 소스 , 애플리케이션

이벤트 처리• Spring Framework2.5 이상부터 Application Context 설정시 자바 어노테이션을 지원• XML ? Annotation 방식 : XML 설정 방식을 쓰면 모든 설정을 자바코드로 부터 외부 XML 에 둠 어노테이션 방식의 경우 자바코드 내에서 DI 설정을 정의 둘 동시에 사용되는 경우 XML 설정 이 우선 주로 데이터소스 , 트랜잭션매니저 , JMX, JMS 커넥션 팩토리등 애플리케이션 • 인프라 스트럭처에는 XML 파일에 저장하고 DI 설정은 어노테이션에서 정의 .• Context 시작 시 모든 Singleton Bean 을 미리 로딩 (preloading) 시킴 -> 초기에 설정 및 환경에 대한 에러

발견 가능함• 다수의 Application Context 구현 클래스 제공 , 다양한 Resource 로딩 방법 제공 (XmlWebApplicationContext,FileSystemXmlApplicationContext,ClassPathXmlApplicationContext)• Spring 의 AOP 기능 , 메시지 자원 핸들링 , 이벤트 위임 , 웹 어플리케이션에서 사용하기 위한 Web Application

Context 와 같은 특정 어플리케이션 컨텍스트를 이용한 통합과 같은 다른 기능을 추가 제공한다

2-1. Ioc Container

2-1-2. Bean Factory, Application Context 분류

Page 10: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

스프링에서 자바 빈을 로딩하는 방법은 BeanFactory 를 이용 하는 방법과 ApplicationContext 를 이용하는 두 가지 방법이 있다 .

Lazy-Loading 설정 파일 

메소드나 클래스가 요청을 받는 시점에 자바 빈의 인스턴스를 만들고 로딩하는 방법이다 . BeanFactory factory = new XmlBeanFactory(    new InputStreamResource(                        new FileInputStream(“ojc.xml"))); // 1OracleJavaComm ojc = (OracleJavaComm) factory.getBean("oracleJavaBean"); // 2

1 번에서 Bean Factory 컨테이너에 의해 ojc.xml 파일이 로드 되더라도 어떠한 빈도 인스턴스화 되지 않고 2 번에서 oracle Java Bean 이 요청을 받는 시점에 인스턴스화 되고 로드 된다 . 즉 getBean 메소드 호출 시 빈이 로드 된다 .

2-1. Ioc Container

2-1-3. Lzay-Loading, Pre-Loading

Page 11: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

Pre-loading 파일 

모든 빈들이 Application Context 컨테이너에 의해 설정파일이 로드 될 때 인스턴스로 만들어지고 로드 된다 .ApplicationContext context = new ClassPathXmlApplicationContext( " ojc.xml"); // 1 OracleJavaComm ojc = (OracleJavaComm) factory.getBean("oracleJavaBean"); // 2 1 번에서 모든 싱글 톤 빈들이 인스턴스화 된다 . 그러므로 빈이 여러 개라면 시간이 소요될 것이다 . 2 번에서는 미리 컨테이너에서 만들어진 빈들이 클라이언트로 리턴 된다 . 스프링 설정파일에 여러 개의 자바 빈이 정의되었다고 모두 자주 사용되는 것은 아닐 수 있다 . 모두 자주 사용되지 않을 수도 있으니 이러한 경우라면 요청이 있을 때 자바 빈을 인스턴스로 만드는 것이 좋을 것이다 .  물론 모두 자주 사용되는 빈이라면 한번에 로드 하는 것도 좋은 방법이다 .

2-1. Ioc Container

2-1-3. Lzay-Loading, Pre-Loading

Page 12: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

“ 오라클자바몰”이라는 회사를 만들어서 내가 잘아는 분야인 차를 팔기로 정했다 . 차량의 구매는 현대자동차와 하고 , 현대자동차에 돈을 지불하고 차를 받기로 했다 . STS New Project Spring Legacy ProjectProject Name : carmakerSimple Projects : Simple Spring Maven 프로젝트 생성 후 - 프로젝트 루트아래의 pom.xml 파일을 오픈 후 스프링 버전을 4.2.0 으로 변경- src/main/java 아래에서 edu.biz.ioc 패키지 생성 <!-- Spring --><spring-framework.version>4.2.0.RELEASE</spring-framework.version>

2-2. Spring Ioc 실습 (XML 기반 , 인터페이스 , 세터주입 )

Page 13: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

2-2. Spring Ioc 실습 (XML 기반 , 인터페이스 , 세터주입 )

Page 14: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

2-2. Spring Ioc 실습 (XML 기반 , 인터페이스 , 세터주입 )

[Money.java] 

package edu.biz.ioc; public class Money {  private int amount; public Money() {} public Money(int amt) { this.amount = amt; } public int getAmount() { return this.amount; } public void setAmount(int amt) { this.amount = amt; }}

[Car.java] 

package edu.biz.ioc; public class Car{ private String name; public Car(String name) { this.name = name; } public String getName() { return this.name; } public void setName(String name) { this.name = name; }}

[HyundaiMaker.-java]

 

package edu.biz.ioc; public class HyundaiMaker { public HyundaiMaker () { } // 생성자  public Car sell(Money money) { System.out.println("I sold a car."); Car car = new Car(“Sonata”); return car; }}

Page 15: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

2-2. Spring Ioc 실습 (XML 기반 , 인터페이스 , 세터주입 )

[src/main/rtesources/ioc.xml] : Project 에서 마우스 우측버튼 ->new -> other -> Spring ->Spring Bean Configuration File

<?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-4.2.xsd"> <!— 아래 부분만 코딩 하세요 <bean id="orderManager" class="edu.biz.ioc.OrderManager"/></beans>

Page 16: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

2-2. Spring Ioc 실습 (XML 기반 , 인터페이스 , 세터주입 )

[OrderManagerApp.java] 

package edu.biz.ioc;import org.springframework.beans.factory.support.DefaultListableBean-Factory;import org.springframework.beans.factory.xml.*;import org.springframework.core.io.*; public class OrderManagerApp { public static void main(String[] args) { BeanFactory factory = new XmlBeanFactory(new FileSystemResource(“src/main/resources/ioc.xml")); OrderManager manager = (OrderManager) factory.getBean("orderManager"); manager.order(); }}

Page 17: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

2-2. Spring Ioc 실습 (XML 기반 , 인터페이스 , 세터주입 )

위 예제에서 

Order Manager 와 Hyundai Maker 는 서로 떼어 놓을 방법이 없다 . 이 두 클래스는 정적으로 결합 (coupling) 되어 있다

하나의 버그를 고치면 그 결과 다른 새로운 버그가 생성되는 ‘두더지잡기 (whack-a-mole)’ 버그를 만든다 .

다른 한편으로 완벽하게 분리된 코드는 아무일 도 못한다 .

자바에서 결합 도를 떨어뜨리는 일반적인 방법은 구현을 인터페이스 뒤로 숨기는 인터페이스 기반 프로그래밍을 하는 것이다 . 이를 통해 클라이언트 클래스에 영향을 주지 않고도 쉽게 구현 클래스가 교체 될 수 있도록 할 수 있다 .

Page 18: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

2-2. Spring Ioc 실습 (XML 기반 , 인터페이스 , 세터주입 )

[CarMaker.java] 

package edu.biz.ioc;  public interface CarMaker { /** 돈을 받고 차를 판다 . */ public Car sell(Money money) ; }

[HyundaiMaker.java 를 인터페이스를 구현하도록 수정 ]  

package edu.biz.ioc;public class HyundaiMaker imple-ments CarMaker{ public HyundaiMaker() { } public Car sell(Money money) { System.out.println("I sold a car."); Car car = new Car("Sonata"); return car; }}

[OrderManager.java 수정 ]

 

package edu.biz.ioc;public class OrderManager {// 만약 인터페이스를 사용하지 않는다면 HyundaiMaker 다른 메이커로 교체된다// 면 아래의 private CarMaker maker 를 포함하여 소스코드가 수정되어야 하지만 // 인터페이스를 사용한다면 new HyundaiMaker () 부분만 수정하면 된다 .private CarMaker maker; // 인터페이스 타입public OrderManager() { // 인터페이스기반이므로 추후 Dae-wooMaker() 로 수정 용이 . this.maker = new HyundaiMaker();} public void order() { Car car = this.maker.sell(new Money(1000));}}

Page 19: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

2-2. Spring Ioc 실습 (XML 기반 , 인터페이스 , 세터주입 )

수정된 코드에 대한 검토 인터페이스 기반이므로 new HyundaiMaker 부분은

쉽게 다른 메이커로 변경 가능하지만 여전히 HyundaiMaker 를 new 하고 있음 . 강한 의존관계

자주 변경되는 구상클래스 (Concrete class) 에 의존하지 말라 .

어떤 클래스를 상속받아야 한다면 , 기반 클래스를 추상 클래스 또는 인터페이스로 만들어서 구현하라 .

어떤 클래스의 참조를 가져야 한다면 참조 대상이 되는 클래스를 추상 클래스 , 인터페이스로 정의하라 .

인터페이스를 만들어서 이 인터페이스에 의존하라 . DIP(Dependency Inversion Principle)

Page 20: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

2-2. Spring Ioc 실습 (XML 기반 , 인터페이스 , 세터주입 )

[DaewooMaker.-java]

 

package edu.biz.ioc; public class DaewooMaker im-plements CarMaker { public DaewooMaker () { }  public Car sell(Money money) { System.out.println("I sold a car."); Car car = new Car(“Tosca”); return car; }}

[OrderManager.java 수정 ]

 

package edu.biz.ioc;public class OrderManager {private CarMaker maker; public OrderManager(String name) { this.maker = new DaewooMaker(); } public void order() { Car car = this.maker.sell(new Money(1000));}}

[OrderManager.java 수정 ]

 

public class OrderManager {private String name; private CarMaker maker;  public OrderManager() { }public void order() { Car car = this.maker.sell(new Money(1000));} //setter 메소드를 통해 CarMaker 타입 객체를 주입 받는다 .public void setMaker(CarMaker maker) { this.maker = maker;}}

실행결과를 확인하여 Daewoo Maker 로 바뀐 것을 확인하자 . 인스턴스를 생성하는 방법의 문제를 해결하기 위해 스프링 프레임워크의 세터주입을 이용하자 .

Page 21: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

2-2. Spring Ioc 실습 (XML 기반 , 인터페이스 , 세터주입 )

[ioc.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-4.2.xsd"> <beans> <bean id="hyundaiMaker" class=" edu.biz.ioc.HyundaiMaker"/> <bean id=“daewooMaker" class=" edu.biz.ioc.DaewooMaker"/> <bean id="orderManager" class="edu.biz.ioc.OrderManager"> <!-- 세터 주입을 의미 --> <property name="maker"> <!-- 이부분을 수정하면 소스수정 없이 maker 교체 가능 --> <ref bean="hyundaiMaker"/> </property> </bean> </beans>

Order Manager App 실행 후 결과 확인하자 .

Page 22: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

2-3. Spring Ioc 실습 ( 어노테이션기반 , 인터페이스 , 세터주입 )

[Money.java] 

package edu.biz.ioc4; import org.springframework.stereotype.Component; @Component("money") // DTO 같은 컴포넌트 클래스임을 의미 , @Named 와 동일public class Money {

private int amount; 

public Money() {}

 public Money(int amt) {

this.amount = amt;}

 public int getAmount() {

return amount;}

 public void setAmount(int amount)

{this.amount = amount;

}}

2-2 에서 작성한 예제를 어노테이션 기반으로 변경 해보자 .

[Car.java] 

package edu.biz.ioc4; import org.springframework.stereotype.Component; @Component("car")public class Car {

private String name; 

public Car() {}

 public Car(String name) {

this.name = name;}

 public String getName() {

return name;}

 public void setName(String name) {

this.name = name;}

}

Page 23: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

2-3. Spring Ioc 실습 ( 어노테이션기반 , 인터페이스 , 세터주입 )

[CarMaker.java] 

package edu.biz.ioc4; public interface CarMaker { // 돈을 받고 차를 판다public Car sell(Money money) ; }

2-2 에서 작성한 예제를 어노테이션 기반으로 변경 해보자 .

[HyundaiMaker.java] 

package edu.biz.ioc4; import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service; @Service("hyundai") //@Named 와 동일 , 서비스계층의 클래스임을 의미public class HyundaiMaker implements CarMaker{

@Autowired //@Inject 와 동일private Car car;

 public Car sell(Money money) {

System.out.println("I sold a Sonata.");car.setName("Sonata");return car;

}}

Page 24: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

2-3. Spring Ioc 실습 ( 어노테이션기반 , 인터페이스 , 세터주입 )

[DaewooMaker.java] 

package edu.biz.ioc4; import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service; @Service(“daewoo")public class DaewooMaker implements CarMaker{

@Autowiredprivate Car car;

 public Car sell(Money money) {

System.out.println("I sold a Tosca.");

car.setName(“Tosca");return car;

}}

2-2 에서 작성한 예제를 어노테이션 기반으로 변경 해보자 .

[OrderManager.java] 

package edu.biz.ioc4; import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.stereotype.Service; @Service("orderManager")public class OrderManager {

private String name;@Autowired // TYPE 이 CarMaker 인것 찾아 자동 주입 , 여러 개인 경우 Qualifier 로 지정@Qualifier("daewoo")private CarMaker maker;

 @Autowired // TYPE 이 Money 인 것을 찾아 자동 주입private Money money;

 public OrderManager() {}

public void order() {money.setAmount(1000);Car car = this.maker.sell(money);

}} 

Page 25: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

2-3. Spring Ioc 실습 ( 어노테이션기반 , 인터페이스 , 세터주입 )

[ioc4.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-4.2.xsd"> 

<beans> <context:annotation-config/> 생략가능 !! <context:component-scan base-package="edu.biz.ioc4"/></beans>

2-2 에서 작성한 예제를 어노테이션 기반으로 변경 해보자 .

Page 26: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

2-3. Spring Ioc 실습 ( 어노테이션기반 , 인터페이스 , 세터주입 )

[OrderManagerApp.java]  

package edu.biz.ioc4; import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext; public class OrderManagerApp {

public static void main(String[] args) {ApplicationContext factory = new

ClassPathXmlApplicationContext("classpath:ioc4.xml");OrderManager manager = (OrderManager)

factory.getBean("orderManager");manager.order();

}}

2-2 에서 작성한 예제를 어노테이션 기반으로 변경 해보자 .

실행 후 결과를 확인하자 .

Page 27: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

2-4. DI 와 관련된 어노테이션

[ 수정된 OrderManagerApp.java]  package edu.biz.ioc4;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import org.springframework.stereotype.Service;@Servicepublic class OrderManagerApp { // 생성자가 아닌 직접 autowiring 은 불가 , static 변수는 autowiring 안된다 .

static OrderManager orderManager; 

@Autowiredpublic OrderManagerApp(OrderManager orderManager) {

OrderManagerApp.orderManager = orderManager;

public static void main(String[] args) { ApplicationContext factory = new ClassPathXmlApplicationContext("classpath:ioc4.xml");

//OrderManager manager = (OrderManager) factory.getBean("orderManager");

orderManager.order();}

}

실행 후 결과를 확인하자 .

Page 28: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI

: 스프링 컨테이너는 base-package 의 클래스를 검색해서 자동으로 자바 빈으로 등록하는 데 이에 해당하는 것이 @Component, @Repository, @Service, @Contoroller, @RestController 어노테이션이다 . 

자동스캔을 위해서는 <context:component-scan base-package="onj.edu.spring" /> 과 같이 base-pack-age 를 기술하며 , 패키지가 여럿인 경우 콤마로 구분하여 기술한다 .

2-4. DI 와 관련된 어노테이션 2-4-1. Auto-Scanning Component (Stereotyping Annotations), @Component, @Repository, @Service, @Controller, @Rest Controller

@Component  

일반적인 용도의 컴포넌트들을 표시하는 기본 스테레오 타입 , 멤버변수와 getter, setter 만 가지고 있는 DTO 같은 컴포넌트를 지칭한다 . 스프링이 @Component 붙은 자바 클래스를 클래스패스 경로에서 자동으로 찾아 Application Context 안에 이름을 부여하고 빈으로 등록한다 . 빈의 기본 Scope 는 songleton 이며 @Scope 어노테이션으로 변경 가능하다 .----------------------------------------------------------------------------------------------------------------------@Component// 하나의 Bean 정의에 대해서 다수의 객체가 존재하며 생략하면 Singleton 으로 생성된다 .@Scope("prototype")   public class Student {       .....}

Page 29: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI2-4. DI 와 관련된 어노테이션 2-4-1. Auto-Scanning Component (Stereotyping Annotations), @Component, @Repository, @Service, @Controller, @Rest Controller

@Repository   

퍼시스턴스 레이어의 DAO 컴포넌트에 부여하는 어노테이션 , @Compone 의 역할과 유사하며 DAO 메소드가 던지는 예외 (Unckecked Exception) 를 스프링의 DataAccessException 으로 변환한다 .----------------------------------------------------------------------------------------------------------------------@Repository   public class EmpRepositoryImpl implements EmpRepository {       .....} @Service   

비즈니스 로직을 담고 있는 서비스 레이어의 서비스 컴포넌트를 가리키며 @Component 어노테이션과 동작은 같지만 서비스 계층의 클래스들은 @Service 어노테이션을 부여하는 것이 코드 가독성이 좋다 .----------------------------------------------------------------------------------------------------------------------@Service   public class EmpServiceImpl implements EmpService {        ..... @Autowired EmpRepository empRepository;}

Page 30: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI2-4. DI 와 관련된 어노테이션 2-4-1. Auto-Scanning Component (Stereotyping Annotations), @Component, @Repository, @Service, @Controller, @Rest Controller

@Controller   

프레젠테이션 레이어의 컨트롤러 컴포넌트----------------------------------------------------------------------------------------------------------------------@Repository   public class EmpRepositoryImpl implements EmpRepository {       .....}

Page 31: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI2-4. DI 와 관련된 어노테이션

@Scope   

일반적으로 @Component, @Service, @Repository 등으로 자동 스캐닝 한 자바 빈은 싱글 톤 형태로 하나만 생성하는데 이를 변경하려면 @Scope 어노테이션을 사용하면 된다 . 즉 빈의 범위를 설정한다 .----------------------------------------------------------------------------------------------------------------------singleton – IoC 컨테이너당 하나의 빈을 리턴prototype – 요구가 있을 때 마다 새로운 빈을 만들어 리턴request - HTTP request 객체당 하나의 빈을 리턴session - HTTP session 당 하나의 빈을 리턴globalSession - 전체 모든 세션에 대해 하나의 빈을 리턴 @Component@Scope("prototype")   // 요구시마다 하나의 새로운 빈을 리턴class Ojc { ……} <bean id="ojc" class="oraclejava.edu.Ojc"   scope="prototype"/>

2-4-2. Context Configuration Annotations (@Scope, @Autowired, @Resource, @Inject, @Required, @Named, @Order, @PostConstruct, @Pre-Destroy)

빈을 주입 받는 경우 아래의 어노테이션이 사용 가능하다 .

Page 32: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI2-4. DI 와 관련된 어노테이션

@Autowired  

Spring Framework 에 종속적인 어노테이션 이다 .빈의 id, name 로 아무거나 맞으면 적용 (Type Driven Injection)여러개의 빈이 검색될 경우 @Qualifier(name="xxx") 어노테이션으로 구분한다 .기본적으로 @Autowired 된 속성은 모두 빈이 주입되어야 한다 . ( 주입될 빈이 없는 경우가 있다면 required=false로 하면 오류는 발생하지 않는다 .)멤버변수 , setter 메소드 , 생성자 , 일반 메소드에 적용 가능

2-4-2. Context Configuration Annotations (@Scope, @Autowired, @Resource, @Inject, @Required, @Named, @Order, @PostConstruct, @Pre-Destroy)

@Resource  

Spring2.5 이상에서 사용가능하며 Spring Framework 에 비종속적으로 권장하는 방식이다 .빈의 name 으로 주입될 빈을 찾는다 .멤버변수 , setter 메소드에 적용가능사용하기 위해서는 jsr250-api.jar 가 클래스패스에 추가되야 한다 . 

[MAVEN 설정 ]<dependency><groupId>javax.annotation</groupId><artifactId>jsr250-api</artifactId><version>1.0</version></dependency>

Page 33: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI2-4. DI 와 관련된 어노테이션

@Inject  

Spring3.0 이상에서 사용가능 하다 .특정 Framework 에 종속되지 않은 어플리케이션을 구성하기 위해서는 @Inject 를 사용할 것을 권장한다 .JSR.330 라이브러리인 javax.inject-x.x.x.jar 파일이 추가되어야 한다 .멤버변수 , setter 메소드 , 생성자 , 일반 메소드에 적용 가능하다 . [MAVEN 설정 ]<dependency>

<groupId>javax.inject</groupId><artifactId>javax.inject</artifactId><version>1</version>

</dependency>

2-4-2. Context Configuration Annotations (@Scope, @Autowired, @Resource, @Inject, @Required, @Named, @Order, @PostConstruct, @Pre-Destroy)

Page 34: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI2-4. DI 와 관련된 어노테이션 2-4-2. Context Configuration Annotations (@Scope, @Autowired, @Resource, @Inject, @Required, @Named, @Order, @PostConstruct, @Pre-Destroy) @Required

 Setter 메소드 위에 기술하여 필수 프로퍼티를 설정하는 용도로 사용된다 .-----------------------------------------------------------------------------------------------------------------------package day1;public class Emp { private String ename; @Required public void setEname(String ename) { this.ename = ename; } public String getEname() { return this.ename; }} 

XML 설정에서 (Beans.xml)… <context:annotation-config/> <bean id="emp" class="day1.Emp"> <!-- 아래 프로퍼티를 설정하지 않으면 오류 --> <!-- <property ename="ename" value= "홍길동 " /> --> </bean> 

main 에서… ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); Emp emp = (Student) context.getBean("emp"); System.out.println(“Ename : " + emp.getEname() ); 

오류메시지 Property 'ename' is required for bean 'emp' 

 @Required 어노테이션이 사용되기 위해서는 RequiredAnnotationBeanPostProcessor 클래스를 빈으로 등록하거나 <context:annotation-config> 설정을 추가하면 된다 .

Page 35: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI2-4. DI 와 관련된 어노테이션 2-4-2. Context Configuration Annotations (@Scope, @Autowired, @Resource, @Inject, @Required, @Named, @Order, @PostConstruct, @Pre-Destroy) @Named

 

JSR-330 의 어노테이션이며 Spring 의 @Component, @Qualifier 와 동일하다 .-----------------------------------------------------------------------------------------------------------------------

@Repository @Namedpublic class EmpDAO { … } public class EmpDAO { … }  @Service @Namedpublic class EmpService { … } public class EmpService { … } @Component @Namedpublic class EmpVO { … } public class EmpVO { … } @Autowiredpublic void setEmp(@Qualifier(“programmer") Emp emp) { … }  아래와 동일 @Injectpublic void setEmp(@Named(“programmer") Emp emp) { … } [MAVEN 설정 ]<dependency>

<groupId>javax.inject</groupId><artifactId>javax.inject</artifactId><version>1</version>

</dependency>

Page 36: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI2-4. DI 와 관련된 어노테이션 2-4-2. Context Configuration Annotations (@Scope, @Autowired, @Resource, @Inject, @Required, @Named, @Order, @PostConstruct, @Pre-Destroy)

Page 37: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI2-4. DI 와 관련된 어노테이션 2-4-2. Context Configuration Annotations (@Scope, @Autowired, @Resource, @Inject, @Required, @Named, @Order, @PostConstruct, @Pre-Destroy) @Order

 Spring4 에서 새로 소개된 @Order 어노테이션은 같은 타입의 빈이 컬렉션 (List 등 )에 Autowired 될 때 그 순서를 지정한다 . (* 낮은 숫자가 우선순위가 높다 ) -----------------------먼저 @Order 를 사용하지 않은 예제를 작성해 보자 . ( 스프링 버전은 4 이상으로 )

[Emp.java]package ojc;public interface Emp {

public void work();}

[Programmer.java]package ojc;import org.springframework.stereotype.Service;@Servicepublic class Programmer implements Emp {

public void work() {System.out.println("Programmer

Working...");}

}

[Designer.java]package ojc;import org.springframework.stereotype.Service;@Servicepublic class Designer implements Emp {

public void work() {

System.out.println("Designer Working...");}

}

[OrderTest.java]@Servicepublic class OrderTest {

@AutowiredList<Emp> emps;public static void main(String[] args) {

ApplicationContext context = new ClassPathXmlApplicationContext("order.xml");

OrderTest test = (OrderTest) context.getBean("orderTest");

for(Emp e : test.emps) {e.work();

}}

}[/src/main/resources/order.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"

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">

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

Page 38: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI2-4. DI 와 관련된 어노테이션 2-4-2. Context Configuration Annotations (@Scope, @Autowired, @Resource, @Inject, @Required, @Named, @Order, @PostConstruct, @Pre-Destroy)  : OrderTest 를 실행하면 다음과 같이 결과가 나타난다 .(Designer 가 List 에 먼저 주입됨 )

[ 실행 결과 ]Designer Working...Programmer Working... 그러나 emps 리스트에 주입되는 빈에 순서가 정의되지 않는다 . 이때 주입되는 순서를 주기 위해 @Order 를 사용하면 된다 . 물론 XML 설정을 이용하여 Programmer, Designer 를 빈으로 등록해 놓고 List<Emp> emps 의 setter 를 이용하여 Collection 형태로 빈을 주입한다면 기술된 빈의 순서대로 List 에 들어가게 된다 . 앞 예제를 수정해 보자 .

[Designer.java]@Service@Order(value=2)public class Designer implements Emp { … }

[Programmer.java]@Service@Order(value=1)public class Programmer implements Emp { … }

이제는 Programmer 가 우선순위가 높아 먼저 출력될 것이다 .

Page 39: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

2. Spring IoC & DI2-4. DI 와 관련된 어노테이션 2-4-2. Context Configuration Annotations (@Scope, @Autowired, @Resource, @Inject, @Required, @Named, @Order, @PostConstruct, @Pre-Destroy)

@PostConstruct  

객체가 생성된 후 별도의 초기화 작업을 위해 실행하는 메소드를 선언한다 .CommonAnnotationBeanPostProcessor 클래스를 빈으로 등록시키거나 <context:annotation-config> 태그를 사용하면 된다 .----------------------------------------------------------

@PreDestroy  

스프링 컨테이너에서 객체 ( 빈 ) 를 제거하기 전에 해야할 작업이 있다면 메소드위에 사용하는 어노테이션 이다 . 이 어노테이션을 사용하기 위해서는 CommonAnnotationBeanPostPro-cessor 클래스를 빈으로 등록하거나 <context:annotation-config> 태그를 사용하면 된다 .

<--------------------------------------------------------class Hello { String name = null; Hello(String name) { this.name = name; } @PostConstruct public initObj() { if (name == null) { name = " 홍길동 "; } }}

Page 40: NCS기반 Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스 ☆무료강의자료 제공/ 구로오라클학원, 탑크리에듀, IT학원, 국비지원교육,

Any Questions ?

THANK YOU FOR YOUR ATTENTION

무료국비지원교육 / 구로자바학원 _ 탑크리에듀 교육센터 http://www.-topcredu.co.kr