티스토리 뷰

1.    스프링의 DI(의존성 주입)에서 의존성이란

-      의존성 주입이란 코드 내부에서 객체 간의 연결을 이루는 것이 아니라, 외부에서 설정을 통해서 객체를 연결하는 패턴이다.

-      + , A객체에서 B객체를 직접 생성하는 방법이 아니라

-      + AB가 필요하다는 신호만 보내고, B객체를 주입하는 것은 외부( 스프링 )에서 이루어지는 방법이다.

-      + 스프링의 경우 의존성 주입을 쉽게 적용할 수 있는 프레임워크가 존재한다.

-      이때 의존성을 나타낼 수 있는 예시로는 Restaurant -------- > 요리사( chef )로 표시할 수 있다.

-      + 이는 요리사 없이는 Restaurant이 존재할 수 없다는 의미이다.

-      + Restaurant의 입장에서는 요리사가 반드시 필요하다는 의미이기도 하다.

 

-      [ 기존 버전 ]

-      Public class Restaurant {

-       

-              // 필드의 종류 3가지 : 1.객체의 고유속성, 2.객체의 상태, 3.부품(집합) 관계

-              Private Chef chef;

-       

-             // 생성자( 생성자를 통한 의존성 주입 ) : 초기화

-            Public Restaurant ( Chef chef ) {

-                      this.chef = chef;   // 생성자를 통한 의존성 주입 ( DI )

-                } // Restaurant ( )생성자

-       

-       } // Restaurant

 

-      [ 스프링 버전 ]

-      Public class Restaurant {

-       

-              // 필드의 종류 3가지 : 1.객체의 고유속성, 2.객체의 상태, 3.부품(집합) 관계

-             @Autowired

-              Private Chef chef;

-       

-       } // Restaurant

 

-      + 스프링에서는 @Autowired를 통해 의존성 주입을 자동으로 요청할 수 있다.

-      + , 스프링에서는 개발자가 직접 생성자를 만들지 않아도 @Autowired를 통해 스프링( 스프링 컨텍스트 )에게 객체 주입 신호를 보내서 객체를 주입 받을 수 있다는 의미이다.

-      + 컴파일이 아닌 실행시에 의존 관계가 완성되는 방식이다.

-      + @Autowired는 생성자 위에도 붙여서 사용할 수 있다.

 

2.    마이바티스와 Quartz와 스프링

-      마이바티스 : SQL 처리 프레임 워크

-      Quartz : Job 스케줄링

-      스프링 :

-      + 이전의 EJB( 분산 병렬 컴포넌트 )가 기술 스펙이 너무 난해하고, 구현이 너무 어려워서 이를 해결하기 위해 Spring이 등장했다.

-      + 스프링( Spring )EJB를 대체하기 위한 경량형( 구현하기 쉬운 ) 분산 병렬 컴포넌트로 구현하기 쉬운 프레임 워크로 등장했으나, 현재는 경량형에서 거리가 멀어지는 중이다.

 

3.    클래스가 자바빈즈 클래스가 되기 위해 지켜야 하는 규약 4가지

-      1 ) 모든 필드는 private이어야 한다. ( OOP의 은닉화 / 캡슐화 성질 ) -> 필수

-      2 ) 각 필드에 대해서 Getter / Setter 메소드를 가져야 한다. -> 필수

-      3 ) Default Constructor(매개변수가 없는 기본 생성자)를 가져야 한다. -> 필수

-      4 ) java.io.Serializable 태그 인터페이스를 implements(구현)해야 한다. -> 선택

-      + 자바빈즈 클래스로부터 생성한 객체를 아래와 같이 부른다.

-      + (1) 자바빈즈 객체 -> 축약형 : 자바빈 -> 축약형 :

-      + 스프링이 의존성 주입(DI)을 하기 위해서는 기본적으로, Spring Context라는 박스 안에 있는 모든 객체가 빈객체이어야 한다. (***)

-      + 그렇기에 Spring Context를 다른 말로 beans container이라고도 한다.

 

4.    @Component

-      자바빈즈 클래스의 타입선언부 위에 @Component 어노테이션을 붙이면, 이 클래스로부터 생성될 빈 객체는 SpringBeans Container에 저장될 객체임을 의미한다.

-      @Component 어노테이션이 불은 모든 자바빈즈 클래스를 한번에 스프링의 빈으로 설정하기 위해서는 root-context.xml 파일에서 <context:component-scan base-package="범위지정(ex.org.zerock.myapp)" /> 태그를 통해 설정할 수 있다.


[ 1. Spring - 의존성 주입 (DI) ] (****)

 

[ 1 - 1. chef 클래스 만들기 ]

 

더보기

[ + 코드 보기 ]

import org.springframework.stereotype.Component;

import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.extern.log4j.Log4j2;


@ToString
@Log4j2
@NoArgsConstructor

@Component("chef")
public class Chef {
	
	// =====================================================================================
	// 자바빈즈 클래스가 되기 위해서는
	// -	1 ) 모든 필드는 private이어야 한다. ( OOP의 은닉화 / 캡슐화 성질 ) -> 필수
	// -	2 ) 각 필드에 대해서 Getter / Setter 메소드를 가져야 한다. -> 필수
	// -	3 ) Default Constructor(매개변수가 없는 기본 생성자)를 가져야 한다. -> 필수
	// -	4 ) java.io.Serializable 태그 인터페이스를 implements(구현)해야 한다. -> 선택
	// =====================================================================================
	// + 다음과 같은 4가지를 지켜야 하지만,
	// + 세프 클래스의 경우 필드가 존재하지 않기에 1번과 2번이 자동으로 통과되고
	// + @NoArgsConstructor로 Default Constructor를 자동 생성해주었기에 자바빈즈 클래스가 된다.
	// =====================================================================================
	
	;;

} // Chef

 

[ 1 - 2. Restuarant 클래스 만들기 ]

 

더보기

[ + 코드 보기 ]

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;


@ToString
@Getter(AccessLevel.PUBLIC)
@NoArgsConstructor

@Component("hotel")
// @Component는 빈 컨테이너에 들어가는 구성요소라는 의미이다.
// 사실 ()안에 지정해 주지 않고 @Component만 작성해도 된다.'
public class Hotel {
	
	// =====================================================================================
	// 자바빈즈 클래스가 되기 위해서는
	// -	1 ) 모든 필드는 private이어야 한다. ( OOP의 은닉화 / 캡슐화 성질 ) -> 필수
	// -	2 ) 각 필드에 대해서 Getter / Setter 메소드를 가져야 한다. -> 필수
	// -	3 ) Default Constructor(매개변수가 없는 기본 생성자)를 가져야 한다. -> 필수
	// -	4 ) java.io.Serializable 태그 인터페이스를 implements(구현)해야 한다. -> 선택
	// =====================================================================================
	// + 다음과 같은 4가지를 지켜야 하지만,
	// + 호텔 클래스의 경우 의존성 객체를 주입받을 필드가 private로 되어있으며,
	// + @Getter와 @Setter로 Getter / Setter 조건을 만족시켰고,
	// + @NoArgsConstructor로 Default Constructor를 자동 생성해주었기에 자바빈즈 클래스가 된다.
	// =====================================================================================
	
	@Setter(onMethod_ = {@Autowired}) // spring Context에게 의존성 주입 시그널 전송
	// + 이는 Setter메소드 위에 @Autowired를 만들어달라는 의미이다.
	private Chef chef;

} // Hotel

[ 1 - 3. Hotel 클래스 만들기 ]

 

더보기

[ + 코드 보기 ]

package org.zerock.myapp.sample;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;


@ToString
@Getter(AccessLevel.PUBLIC)
@NoArgsConstructor

@Component("hotel")
// @Component는 빈 컨테이너에 들어가는 구성요소라는 의미이다.
// 사실 ()안에 지정해 주지 않고 @Component만 작성해도 된다.'
public class Hotel {
	
	// =====================================================================================
	// 자바빈즈 클래스가 되기 위해서는
	// -	1 ) 모든 필드는 private이어야 한다. ( OOP의 은닉화 / 캡슐화 성질 ) -> 필수
	// -	2 ) 각 필드에 대해서 Getter / Setter 메소드를 가져야 한다. -> 필수
	// -	3 ) Default Constructor(매개변수가 없는 기본 생성자)를 가져야 한다. -> 필수
	// -	4 ) java.io.Serializable 태그 인터페이스를 implements(구현)해야 한다. -> 선택
	// =====================================================================================
	// + 다음과 같은 4가지를 지켜야 하지만,
	// + 호텔 클래스의 경우 의존성 객체를 주입받을 필드가 private로 되어있으며,
	// + @Getter와 @Setter로 Getter / Setter 조건을 만족시켰고,
	// + @NoArgsConstructor로 Default Constructor를 자동 생성해주었기에 자바빈즈 클래스가 된다.
	// =====================================================================================
	
	@Setter(onMethod_ = {@Autowired}) // spring Context에게 의존성 주입 시그널 전송
	// + 이는 Setter메소드 위에 @Autowired를 만들어달라는 의미이다.
	private Chef chef;

} // Hotel

[ 1 - 4. root-context에 빈 객체 등록하기 ] (****)

 

<?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.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
	
	<!-- Root Context: defines shared resources visible to all other web components -->

	<!-- 여기 안에 속한 것은 모두 빈 타입으로 등록하겠다는 의미이다. -->
	<context:component-scan base-package="org.zerock.myapp.sample" />
		
</beans>

[ + 빈이 등록된 것을 확인 ]

 

 

[ 1 - 5. pom.xml파일 수정 - Spring 부분에서 spring-text 추가 ] (***)

 

더보기

[ + 코드 보기 ]

 <!-- ================ Spring (밑의 2개는 최소한 꼭) =============== -->

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${org.springframework-version}</version>
			<scope>test</scope>
		</dependency>

 

[ 1 - 6. 실행 클래스에서 의존성 확인해 보기 ] (****)

 

더보기

[ + 코드 보기 ]

import java.util.Objects;
import java.util.concurrent.TimeUnit;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.Timeout;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.zerock.myapp.sample.Hotel;

import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;


// Lombok's annotation
@Log4j2
@NoArgsConstructor // JUNIT 테스트 클래스의 필수 사항

//================================================
// For JUnit 5 (***)
// JUnit 테스트 메소드 수행시, Spring FrameWork를 함께 구동시키는 구동자 설정
// @ExtendWith는 스프링 프레임워크 구동하는 클래스 지정
@ExtendWith(SpringExtension.class)
//================================================
// For JUnit 4
// JUnit 테스트 메소드 수행시, Spring FrameWork를 함께 구동시키는 구동자 설정
// @RunWith(SpringJUnit4ClassRunner.class)
// @RunWith(SpringRunner.class)
//================================================

//================================================
// JUnit4와 5에서 모두 공통으로 함께 실행될 Spring FrameWork의 설정파일을 알려주는 역할
// file로 지정하면 절대 경로가 아니라 프로젝트 아래의 파일을 확인하게 된다.
@ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/spring/**/*.xml" })
//================================================

// JUnit-jupiter's annotation
@TestInstance(Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class DiBySetterTests {
	
//	@BeforeAll
//	void beforeAll() {}
	
	// 의존성 주입(DI)
	@Autowired
	private Hotel hotel;
	
	// ================================================
	// JUnit5에서는 자유롭게 이름을 작성해도 된다.
	// ================================================
	
	@Test
	@DisplayName("contextLoads")
	@Order(1)
	@Timeout(value=1000, unit = TimeUnit.MILLISECONDS)
	void contextLoads() {
		
		log.trace("contextLoads() invoked.");
		
		Objects.requireNonNull(this.hotel);
		log.info("\t + this.hotel : {}", this.hotel);
		// + this.hotel : Hotel(chef=Chef()) ( 호텔 객체가 들어왔음을 알 수 있다. )
		// + 호텔 객체 빈 안에도 세프 객체 빈이 필드로 주입된 것을 알 수 있다.
		
	} // contextLoads
	
	// ================================================
	// JUnit4 버전으로 이름 짓기
	// ================================================
	
	@Test
	@DisplayName("testDependencyInjection")
	@Order(2)
	@Timeout(value=1000, unit = TimeUnit.MILLISECONDS)
	void testDependencyInjection() {
		
		log.trace("testDependencyInjection() invoked.");
		
		Objects.requireNonNull(this.hotel);
		log.info("\t + this.hotel : {}", this.hotel);
		// + this.hotel : Hotel(chef=Chef()) ( 호텔 객체가 들어왔음을 알 수 있다. )
		// + 호텔 객체 빈 안에도 세프 객체 빈이 필드로 주입된 것을 알 수 있다.
		
	} // testDependencyInjection
	
	// ================================================

} // end class

[ 2. Spring - 의존성 주입 (DI)할 수 있는 어노테이션 종류 ] (****)

 

더보기

[ + 코드 보기 ]

	// ================================================
	// 의존성 주입(DI) 어노테이션 종류 
	// ================================================
	
	// @Setter가 가장 추천되는 방식이다. - 세터 메소드를 통해 주입된다. (****)
	// @Setter(onMethod_ = @Resource)
	// @Setter(onMethod_ = @Inject)
	// @Setter(onMethod_ = @Autowired)
	
	// @Resource
	// @Inject
	@Autowired
	private Hotel hotel;

[ 3. Spring - @Setter(onMethod_ = {@Autowired}) ] (**)

 


 

 

 

728x90
댓글
«   2024/11   »
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
최근에 올라온 글
Total
Today
Yesterday
공지사항