IoC는 프로그램이 동작하는데 메소드나 객체의 호출 작업을 개발자가 아닌 프로그램이 작동하는 컨테이너에서 직접 관리하는 것을 말한다. Spring은 IoC 구조를 통해서 프로그램 동작 시 필요한 객체의 생성부터 생명 주기까지를 직접 수행한다.
단순하게 제어의 역전이라고 하며 객체의 의존성을 역전시켜서 객체 간이 결합도를 낮추고 유연한 코드를 작성할 수 있도록 한다. IoC 방식으로 프로그램이 동작하면 코드의 중복이 줄어 가독성을 높일 수 있고 유지 보수 또한 수월해진다는 장점이 있다.
스프링이 IoC 방식으로 관리하는 클래스들을 의미한다. 빈은 스프링이 직접 생성과 제어를 담당하게 된다.
스프링의 IoC를 담당하는 핵심이 되는 컨테이너로 Bean을 등록, 생성, 조회, 반환하는 기능을 담당한다. Bean들을 관리하는 역할을 담당하는 컨테이너라고 할 수 있다. 사용할 Bean을 구하는 메소드로getBean()
를 제공한다. 등록된 Bean 객체를 반환하며 첫 번째 파라미터로 Bean의 이름, 두 번째 파라미터로 Bean의 타입을 작성할 수 있고 둘 중 하나만 작성해도 해당하는 Bean을 반환한다.
BeanFactory를 확장한 IoC 컨테이너로 Bean을 등록하고 관리하는 기능은 BeanFactory와 동일하지만 스프링이 제공하는 각종 부가 서비스를 추가로 제공한다. BeanFactory 인터페이스를 구현한 최상위 구현체이다.
ApplicationContext를 구현한 클래스로 일반적인 xml 형태의 문서를 읽어서 해당 문서에 등록된 Bean들을 관리하는 컨테이너 역할을 한다.
GenericXmlApplicationContext context
=new GenericXmlApplicationContext("classpath:applicatonContext.xml");
Student student=context.getBean("student",Student.class);
//해당 이름의 Bean을 해당 클래스 타입으로 반환
Student student=context.getBean(Student.class);
//해당 클래스 타입의 Bean을 반환
Student student=(Student)context.getBean("student");
//해당 이름의 Bean을 Object 타입으로 반환
ApplicationContext 혹은 BeanFactory가 IoC를 적용하기 위해서 사용하는 설정 정보들을 말한다. Configuration metadata(설정 메타 정보)는 IoC 컨테이너에 의해 관리되는 Bean 객체를 생성하고 구성할 때 사용한다.
DI(Dependency Injection)은 IoC 구현의 핵심 기술이라고 할 수 있는데 사용하는 객체를 직접 생성해서 만드는 것이 아니라 컨테이너가 Bean의 설정 정보를 읽어와서 자동으로 해당 객체에 연결하는 것을 의미한다.
즉 등록된 Bean들을 필요한 시점에 저장해두는 것을 말하는데 이렇게 의존성 주입을 하게 되면 해당 객체를 수정해야 할 상황이 생겼을 때 소스 코드의 수정을 최소화할 수 있게 된다.
의존성 주입을 받는 Setter 메소드를 만들고 이를 통해서 의존성 주입한다. Setter 메소드를 통해서 의존 관계가 있는 Bean을 주입하기 위해서는 <property>
태그를 이용할 수 있다.
<bean id="ref에 들어갈 이름" class="주입할 객체(패키지명 포함)"/>
<bean id="객체 이름" class="Bean으로 등록할 클래스(패키지명 포함)">
<property name="사용할 이름" value="이름에 들어갈 값"/>
<property name="사용할 이름" ref="의존성 주입할 객체"/>
<bean>
<!-- example -->
<beans:bean id="dept" class="com.bs.spring.beantest.Department"/>
<beans:bean id="emp" class="com.bs.spring.beantest.Employee"
init-method="initialMethod" destroy-method="destroyMethod">
<beans:property name="name" value="Lee"/>
<beans:property name="age" value="26"/>
<beans:property name="address" value="서울"/>
<beans:property name="salary" value="3000000"/>
<beans:property name="dept" ref="dept"/>
</beans:bean>
필요한 의존성을 포함하는 클래스에 생성자를 만들어놓고 이를 통해서 의존성을 주입한다. <constructor-arg>
태그를 이용해서 의존성을 주입할 수 있고 해당 방식은 생성자의 파라미터를 이용하기 때문에 한 번에 여러개의 객체 주입이 가능하다. 필드 선언 순서에 따라 index 속성을 통해서도 접근할 수 있다.
<bean id="ref에 작성할 이름" class="해당 객체 이름(패키지 포함)"/>
<bean id="불러올 객체 이름" class="클래스명(패키지 포함)">
<constructor-arg index="0" value="값"/>
<constructor-arg index="1" ref="주입할 객체"/>
</bean>
<!-- example -->
<beans:bean id="dept" class="com.bs.spring.beantest.Department">
<beans:constructor-arg index="0" value="1"/>
<beans:constructor-arg index="1" value="개발부"/>
<beans:constructor-arg index="2" value="판교"/>
</beans:bean>
<beans:bean id="emp2" class="com.bs.spring.beantest.Employee">
<beans:constructor-arg index="0" ref="dept"/>
</beans:bean>