-
[Java Spring] IoC, DI (의존성 주입 방법 xml, annotation)Programming/Java 2022. 10. 30. 03:39반응형
IoC(Inversion of Control), 제어의 역전
: 객체 생성을 프레임워크가 유연하게 제어함으로써 객체간 결합도를 줄여, 유연성 증가, 코드 중복 제어, 유지 보수의 편리성 증가
- 스프링이 모든 의존성 객체를 스프링이 실행될 때 다 만들어주고 필요한 곳에 주입
- Bean들은 싱글턴 패턴의 특징을 가지며, 제어의 흐름을 사용자가 컨트롤하지 않고 스프링에게 맡겨 작업 처리[ 일반적인 객체 제어 과정 ]
1. 객체 생성
2. new 키워드를 통해 의존성 객체 생성(클래스 내부에서 생성)
3. 의존성 객체의 메소드 호출
[ 스프링의 객체 제어 과정 ]
1. 객체 생성
2. 의존성 객체 주입 (스프링이 만들어놓은 객체를 주입)
3. 의존성 객체의 메소드 호출DI (Dependency Injection), 의존성 주입
: 외부에서 두 객체간의 관계를 결정해줌으로써, 클래스 레벨에서 의존관계가 고정되지 않고 런타임시 관계를 동적으로 주입 → 유연성 확보 및 결합도 감소
[ 의존성 주입을 하지 않았을 경우 ]
컴퓨터를 1대 판매하는 Store 클래스가 있다고 할 때, 보통의 객체 생성은 아래와 같은 방법으로 가능
// 강한 결합 // Store클래스는 Computer 클래스에 의존함 /* 문제점 * 1. 강한 결합으로 인해 Computer가 아닌 다른 상품을 판매하고 싶다면, 생성자 변경이 필요 -> 유연성 감소, 유지보수 어려움 * 2. 객체 간 관계가 아닌 클래스 간 관계가 맺어짐으로써 객체 지향 프로그래밍에서 멀어짐 */ public class Store { private Computer computer; // public Store() { this.computer = new Computer(); } }
[ 의존성 주입을 할 경우 ]
다형성의 원리에 의해, Computer 등의 상품을 하나로 묶어줄 Interface 생성하여 Store가 인터페이스를 통해 실제 객체를 주입받도록 함
- Spring에서는 애플리케이션 실행 시점에 필요한 객체(빈)을 생성하여 의존성이 있는 두 객체를 연결하기 위해 한 객체를 다른 객체로 주입시켜주는 역할을 해 줌
※ Spring IoC 컨테이너가 관리하는 자바 객체를 빈(Bean)이라고 하며, ApplicationContext에 해당 객체가 만들어져야 의존성 주입을 할 수 있음// 상품들을 묶어줄 Product 인터페이스 생성 public interface Product { } // Product 인터페이스를 implement한 클래스 public class Computer implements Product { } public class Labtop implements Product { } public class Store { private Product product; // 어떤 물건을 팔지 외부에서 상품을 주입 받아야 함 public Store(Product product) { this.product = product; } }
Spring IoC Container
: Bean의 객체화 조립, 관리, 사용 소멸에 대한 처리 담당
- Bean Factory: 프레임워크 설정과 기본 기능을 제공하는 컨테이너, 모든 유형의 객체 관리 가능한 메커니즘 제공
- ApplicationContext: BeanFactory 하위 인터페이스로 이벤트 처리, 국제화용 메시지처리, AOP 통합 기능 제공
- WebApplicationContext: 웹 환경에서 Spring을 사용하기 위한 기능 추가. 대표적 구현 클래스로 XmlWebApplicationContext가 있음의존성 주입 방법
1. Bean 생성 및 설정
1-1. xml 방식
: xml 파일에 모든 bean 객체를 등록하고, 의존관계를 설정해주는 방법
- id: 스프링 컨테이너에서 사용할 bean 고유의 식별자
- class: 객체화할 객체의 클래스 전체 경로 (정규화된 자바 클래스 이름)
- scope: 객체의 범위 (기본 singleton이며 prototype 설정시에는 객체 주입시마다 새로운 객체를 생성함)- constructor-arg: 생성時 생성자에 전달할 인수
- property: 생성時 bean setter에 전달할 인수
// 기존 자바코드 방식의 의존성 생성 과정 // 0. Exam 객체 생성 Exam exam = new MidtermExam(); // 1. 생성자를 통해 결합 ExamConsole console = new InlineExamConsole(exam); // 2. setter를 통해 결합 ExamConsole console = new InlineExamConsole(); console.setExam(exam); // 스프링 프레임워크를 통한 의존성 주입 과정 // xml파일에 bean객체들 생성 후 주입. // 0. Exam 빈 객체 생성 <bean id="exam" class="spring.di.entity.MidtermExam" /> // 1. 생성자를 통해 의존성 주입 <bean id="console" class="spring.di.ui.InlineExamConsole"> <constructor-arg ref="exam" /> </bean> // 2. setter를 통해 의존성 주입 <bean id="console" class="spring.di.ui.InlineExamConsole"> // name 뒤는 setExam을 의미, ref 뒤는 의존성 주입 대상 빈 객체의 id를 의미 <property name="exam" ref="exam" /> </bean>
1-2. Annotation 방식
: xml 파일에는 Bean등록을 위한 대상 패키지만 설정하고 객체를 생성할 대상 클래스에 어노테이션 표시를 하는 방법
- @Component: 스프링에서 관리되는 객체임을 표시하기 위해 사용되는 가장 기본적 annotation
※ Component의 기능을 좀 더 명확하게 하기 위해 명시적으로 아래와 같이 분리 사용함 (aspect에 연관성 부여)
- @Controller: 클라이언트로부터 요청이 왔을 때 지정된 뷰에 모델 객체를 넘겨주는 역할
즉, 요청에 따라 어떤 처리를 할지 결정하여 service에 넘겨주고 service가 처리한 내용을 view에 넘김- @Service: 비즈니스 로직이나 repository layer를 호출하는 함수에 사용. 비즈니스 로직을 수행 결과를 Controller에 넘김
- @Repository: 외부 DB에 접근하는 코드(DAO)
- @Autowired: 의존성을 주입할 대상 위에 작성(xml에서는 constructor-arg, property 태그로 명시
- @Qualifier: 주입 대상이 두 개 이상이거나 빈 객체일 경우, bean을 지정하여 식별 가능하게끔 함
- 어노테이션 방식의 경우, 생성되는 bean 객체의 이름은 클래스 첫 글자를 소문자로 바꾼 것
임의 지정하고 싶다면 @Component(value="bean-name")형태로 지정 가능// xml파일에 Annotation으로 Bean을 등록할 대상 패키지 설정 <context:component-scan base-package="spring.di.*" />
// 각 클래스에 어노테이션을 붙여 Bean객체로 만듦 @Component public class MidtermExam implements Exam { ... } @Service public class InlineExamConsole implements ExamConsole { @Autowired // 의존성 주입할 대상에 작성 private Exam exam; ... }
2. 스프링 컨테이너 객체 생성
- main함수에서 스프링 컨테이너 생성 후, 빈 객체 가져온 후 사용 가능
public class Test { public static void main(String[] args) { Application context context = new GenericXmlApplicationContext("spring/di/applicationContext.xml"); // xml설정파일이 있는 주소 ExamConsole console = context.getBean(ExamConsole.class); console.print(); } }
반응형'Programming > Java' 카테고리의 다른 글
[Java Spring] Spring Security의 개념 및 처리 과정 (0) 2023.01.24 [Java Spring] AOP 개념 및 사용 방법(AspectJ, xml, annotation) (0) 2022.10.30 [Java Spring] 스프링의 MVC 구조 (0) 2022.10.21 [Java Spring] 스프링 프레임워크란? (0) 2022.10.21 [Java 자바] 14. 람다식 (0) 2022.09.14