STUDY/SPRING

스프링(3.0) 의존성 주입

Anne of Green Galbes 2019. 4. 15. 17:17

스프링 예제 1 : 생성자를 이용한 의존성 주입

○ 중간 관리자도 app-context.xml에서 객체 생성


1. 인터페이스 생성

○ MessageService.java

package com.exe.springdi4;

public interface MessageService {

//public static abstract 생략

String getMessage();

}


2. MyMessageService.java

○ 인터페이스를 상속 받아 메소드 작성

package com.exe.springdi4;

public class MyMessageService implements MessageService {

public String getMessage() {

return "안녕 방가방가...";

}

}


3. 중간관리자 생성

○ ServiceConsumer.java

○ 중간에서 값을 받아서 Main에 넘겨주는 역할

package com.exe.springdi4;

public class ServiceConsumer {

//값을 받아서 초기화할 변수 생성

MessageService ms;

//생성자 생성

//넘어올 값을 넣어줌

//ServiceConsumer의 객체가 생성되면서 의존성 주입으로 값을 ms의 값을 넣어줌

//MessageService ms = (MessageService)context.getBean("messageService");의 역할

public ServiceConsumer(MessageService ms) {

this.ms = ms;

}

public void consumerService() {

String message = ms.getMessage();

System.out.println(message);

}

}


4. MessageMain.java

○ 기존에 중간관리자에서 읽었던 app-context.xml을 main에서 읽어줘야 한다

package com.exe.springdi4;

import org.springframework.context.support.GenericXmlApplicationContext;

public class MessageMain {

public static void main(String[] args) {


//app-context.xml은 자바에서 자동으로 읽어지지 않는다

//main에서 읽어야 한다

GenericXmlApplicationContext context = new GenericXmlApplicationContext("app-context.xml");

ServiceConsumer sc = (ServiceConsumer)context.getBean("serviceConsumer");

sc.consumerService();

}

}


5. app-context.xml

<bean id="serviceConsumer" class="com.exe.springdi4.ServiceConsumer">

<!-- 생성자를 이용한 의존성 주입 -->

<!-- 이 객체가 생성되기 위해서는 messageService가 반드시 필요 -->

<!-- 제어의 역전(IoC) -->

<constructor-arg ref="messageService"/>

</bean>

<bean id="messageService" class="com.exe.springdi4.MyMessageService"/>


6. 생성자 의존성 주입


스프링 예제 2-1 : 메소드를 이용한 의존성 주입


1. TimeService.java

package com.exe.springdi4;

public interface TimeService {

public String getTimeString();

}


2. MyTimeService.java

○ 인터페이스를 상속받아 출력값을 만드는 역할

package com.exe.springdi4;

import java.text.SimpleDateFormat;

import java.util.Date;

public class MyTimerService implements TimeService {

public String getTimeString() {

//SimpleDateFormat.LONG :

//간단하게 날짜를 지정해주는 형식을 받음

SimpleDateFormat sdf = (SimpleDateFormat)SimpleDateFormat

.getDateTimeInstance(SimpleDateFormat.LONG, SimpleDateFormat.LONG);

String now = sdf.format(new Date());

//날짜를 반환

return now;

}

}


3. ServiceConsumer.java

○ 중간에서 값을 받아서 Main에 넘겨주는 역할

○ 객체 생성

//기본생성자가 있어야 오버로딩된 생성자 사용 가능 → 위(예제1)에서 오버로딘된 생성자를 사용했기 때문

public ServiceConsumer() {}


//메소드로 의존성 주입

TimeService ts;

public void setTimeService(TimeService ts) {

this.ts = ts;

}

○ 메소드 호출

public void consumerService() {


//생성자로 의존성 주입

String message = ms.getMessage();

System.out.println(message);

//메소드 의존성 주입1

//메소드 호출

String time = ts.getTimeString();

System.out.println(time);


}

}


4. app-context.xml

○ property의 이름은 setter(ServiceConsumer.java)에서 set을 뺀 후, 맨 앞글자를 소문자로 바꾼 것과 동일해야 한다

<bean id="serviceConsumer" class="com.exe.springdi4.ServiceConsumer" autowire="byName">

<constructor-arg ref="messageService"/>

<property name="timeService" ref="timeService"/>

</bean>

<bean id="messageService" class="com.exe.springdi4.MyMessageService" />

<bean id="timeService" class="com.exe.springdi4.MyTimerService"/>


스프링 예제 2-2 : 메소드를 이용한 의존성 주입


1.JobService.java

package com.exe.springdi4;


public interface JobService {

public void getJob();

}


2. MyJobService.java

○ 인터페이스를 상속받아 출력값을 만드는 역할

package com.exe.springdi4;

public class MyJobService implements JobService {

public void getJob() {

System.out.println("나는 프로그래머 입니다.");

}

}


3. ServiceConsumer.java

○ 중간에서 값을 받아서 Main에 넘겨주는 역할

○ 객체 생성

메소드로 의존성 주입

JobService js;

public void setJobService(JobService js) {

this.js = js;

}


○ 메소드 호출

public void consumerService() {


//생성자로 의존성 주입

String message = ms.getMessage();

System.out.println(message);

//메소드 의존성 주입1

//메소드 호출

String time = ts.getTimeString();

System.out.println(time);

//메소드 의존성 주입

js.getJob();

}

}


4. app-context.xml

autowire="byName"

- property를 작성하지 않아도 이름이 동일하면 알아서 넘어간다

<bean id="serviceConsumer" class="com.exe.springdi4.ServiceConsumer" autowire="byName">

<constructor-arg ref="messageService"/>

<property name="timeService" ref="timeService"/>

</bean>

<bean id="messageService" class="com.exe.springdi4.MyMessageService" />

<bean id="timeService" class="com.exe.springdi4.MyTimerService"/>

<bean id="jobService" class="com.exe.springdi4.MyJobService"/>


스프링 예제 3 : 어노테이션 사용


1. app-context.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 https://www.springframework.org/schema/beans/spring-beans-3.0.xsd

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


<description>Example configuration to get you started.</description>


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

</beans>


2. Servlet-Consumer.java

○ 의존성주입 수행

 - @Autowired : app-context.xml의 <constructor-arg ref="messageService"/> 이 작업

 - Setter 메서드, 생성자 메서드 또는 필드(프로퍼티)에 직접 설정 해서 자동으로 의존성 주입이 수행되도록 구성

 - 알아서 값을 받아오기 때문에 setter가 필요 없다

 - MessageService가 생성자로 의존성 주입을 하기 때문에 기본 생성자를 작성해야함

@Autowired

MessageService ms;


public ServiceConsumer() {}

@Autowired

TimeService ts;

@Autowired

JobService js;


○ 이름 중복 방지

 - @Qualifier("사용자 정의")

@Autowired

@Qualifier("messageService")

MessageService ms;


3. My□□□□□Service.java

○ 어노테이션을 사용하여 객체 생성

 - @Component("사용자 정의")

   : app-context.xml의 <bean id="messageService" class="com.exe.springdi4.MyMessageService"/> 이 작업

 - 자동으로 빈 등록

@Component("messageService")

public class MyMessageService implements MessageService {

public String getMessage() {

return "안녕 방가방가...";

}

}


○ 영역 지정

 - @Scope(value="범위")

 - 기본 값은 : prototype

 - 자동으로 등록되는 빈의 범위 지정 : singleton, prototype, session …

@Scope(value="prototype")

public class MyMessageService implements MessageService {

public String getMessage() {

return "안녕 방가방가...";

}

}


자주 사용하는 이노테이션


@Component

○ 자동으로 빈 등록


@Scope

○ 자동으로 등록되는 빈의 범위 지정

○ singleton, prototype, session …


@Required

○ Setter 메서드에 지정해서 반드시 설정해야 하는 필수 프로퍼티 정의


@Autowired

 Setter 메서드, 생성자 메서드 또는 필드(프로퍼티)에 직접 설정 해서 자동으로 의존성 주입이 수행되도록 구성


@Autowired with (required = false) Option

 컨테이너가 자동으로 의존성 주입을 수행할 때 대상 Bean을 발견하지 못해도 오류를 발생시키지 않도록 설정


@Qualifier

 @Autowired와 함께 사용되어서 자동 의존성 주입이 수행될 대상 Bean을 구체적으로 설정

 같은 타입의 Bean이 두 개 이상 등록된 경우 @Autowired에 발생할 수 있는 모호성 제거


@Resource

 @Autowired + @Qualifier와 같은 효과