Programming/Spring

02. SpringDI / 생성자 * setter 방식 / SpEL

Nolja놀자 2021. 4. 6. 16:20
반응형

 

 

 

IoC란 Inversion of Control의 줄임말로 한글로 번역하면 제어의 역전이라는 말이다.

"제어의 역전" 이라는 의미는 말 그대로 메소드나 객체의 호출작업을 개발자가 결정하는 것이 아니라,

외부에서 결정되는 것을 의미한다.

 

제어의 역전 개념은 이미 폭넓게 적용되어 있다. 일반적으로 자바 프로그램은 main() 메소드에서 시작해서

개발자가 미리 정한 순서를 따라 객체가 생성되고 실행된다.

그런데 서블릿을 생각해보자. 서블릿을 개발해서 서버에 배포할 수는 있지만, 배포하고 나서는 개발자가

직접 제어할 수 있는 방법은 없다. 대신 서블릿에 대한 제어 권한을 가진 컨테이너가 적절한 시점에

서블릿 클래스의 객체를 만들고 그 안의 메소드를 호출한다.

 

이 방식은 대부분의 프레임워크에서 사용하는 방법으로,

개발자는 필요한 부분을 개발해서 끼워 넣기의 형태로 개발하고 실행하게 된다.

프레임워크가 이러한 구조를 가지기 때문에, 개발자는 프레임워크에 필요한 부품을 개발하고,

조립하는 방식의 개발을 하게 된다.

이렇게 조립된 코드의 최종 호출은 개발자에 의해서 제어되는 것이 아니라,

프레임워크의 내부에서 결정된 대로 이뤄지게 되는데, 이러한 현상을 "제어의 역전"이라고 표현한다.

 

스프링은 그 자체가 "구조를 설계할 수 있도록 만들어졌다" 라는 뜻이다. 

 

대부분 프레임워크에서 IoC를 적용한다. 때문에 스프링을 IoC 컨테이너라고만 해서는 스프링을 정확히 정의할 수 없다.

스프링이 여타 프레임워크와 차별화돼서 제공해주는 기능은 의존관계 주입이라는 새로운 용어를 사용할 때

분명히 들어난다.

 

 

1. Spring container


- Java 객체("bean")들의 life-cycle 관리

- DI 

DI란 Dependency Injection의 줄임말로 한글로 번역하면 의존성 주입이라는 말이다.

"의존성 주입"은 제어의 역행이 일어날 때 스프링이 내부에 있는 객체들간의 관계를 관리할 때 사용하는 기법이다.

자바에서는 일반적으로 인터페이스를 이용해서 의존적인 객체의 관계를 최대한 유연하게 처리할 수 있도록 한다.

 

의존성 주입은 말 그대로 의존적인 객체를 직접 생성하거나 제어하는 것이 아니라, 

특정 객체에 필요한 객체를 외부에서 결정해서 연결시키는 것을 의미한다.

즉, 우리는 클래스의 기능을 추상적으로 묶어둔 인터페이스를 갖다 쓰면 되는 것이다.

나머지는 스프링에서 객체를 주입해주기 때문이다.

따라서 이러한 의존성 주입으로 인해 모듈 간의 결합도가 낮아지고 유연성이 높아진다.

 

 

 

* container 종류

1) beanFactory interface 구현체

: getBean(String name, Class <T> requiredType)

2) ApplicationContext interface 및 그 sub-interface 구현체

: BeanFactory를 확장하여 다양한 부가 기능 제공

-> Annotation 기반 설정, Java code 기반 설정, 웹 애플리케이션 관련 기능, 트랜잭션 처리, 메시지 처리 등

 

 

 

 

 

 

 

GenericXmlApplicationContext : XML file 을 설정 정보로 사용

AnnotationConfigApplicationContext : @Configuration이 적용된 java class 의 설정 정보를 이용

XmlWebApplicationContext /  AnnotationConfigWebApplicationContext : Spring MVC framework에서 사용

ex)

 

 

 

 

 

 

2. 의존 관계 설정 (DI)


1) 생성자 방식 : 가장 근접한 타입의 인자를 가진 생성자를 선택

* <Value>를 통해 전달된 값은 기본적으로 String 으로 간주

 

* "c" namespace를 이용한 설정

: 순서가 중요 !

 

 

2) Setter method

 

 

 

: name을 필드이름과 동일하게 설정하기 때문에 순서를 바꿔도 상관없다.

 

* "p" namespace 를 이용한 설정

 

 

 

 

 

3. 생성자 방식 vs Setter 방식


생성자 방식

: Bean 객체를 생성하는 시점에 모든 의존 객체가 주입됨

: 성능상 유리하고, 객체를 사용하기 전에 필요한 의존 객체가 모두 주입된 상태이므로 NullPointException 가능성이 낮음

단, 생성자가 많은 경우 순서대로 객체를 전달하기 때문에 헷갈릴수있다.

 

Setter method 방식

: 각 필드마다 필요한 의존 객체를 주입하므로 설정이 명확하고 용이함

:  setter 별로 실행되므로 성능이 다소 저하되고, setter 실행이 누락된 경우 NullPointException 발생 가능

 

 

 

 

 

4. Lookup method Injection


 

 

4. Collection Wiring


Bean Property가 Collection type인 경우

 

 

 

원소 정의 :

* <value type="java.lang.Double">1.5</value> 이런 식으로 속성 지정 가능

 

 

: Bean property가 generic type으로 선언되 경우, 값이 자동으로 변환됨 !

 

 

 

예시) Collection type

 

-> java 파일에서 Collection, List, 배열 타입으로 선언된 경우 사용 가능

 

-> java 파일에서 Collection, 배열 타입으로 선언된 경우 사용 가능

-> 중복 제거

 

 

 

예시) Map type

 

 

 

 

 

* Properties 는 key와 value가 모두 String인 Map과 같음

 

 

 

 

 

 

5. SpEL


Spring Expression Language

형식 : #{...}

 

** value-ref 가 아닌 value 속성을 사용한다 !!

** 해당 값이 private이면 getSong()을 호출해야 하며, getter 가 존재해야 한다.

 

 

 

* T() : 클래스 이름을 인자로 지정

 

 

 

 

 

# 출처

https://jobc.tistory.com/30

반응형