- Spring IOC

IOC ( Inversion of Control)란 즉 제어의 역전이다.

 

제어의 역전이란?

 

제어권이 역전되다, 기존의 제어방식이 뒤바뀌었다는 것

메서드나 객체의 호출작업을 개발자가 결정하는 게 아닌, 외부에서 결정되는 것을 의미한다.

 

이로 인해 객체 간의 결합도를 줄이고 유연한 코드를 작성할 수 있게 되어 가독성, 코드중복, 유지보수를 용이하게 한다.

기존
객체 생성 → 의존성 객체 생성 → 의존성 객체 메서드 호출

스프링 제어의 역전
객체 생성 → 의존성 객체 주입 → 의존성 객체 메소드 호출
의존성 객체를 직접 생성하지 않고 제어권을 스프링에게 위임하여 스프링이 만들어놓은 객체를 주입한다.

 


 

- DI

DI (Dependency Infection)란 스프링이 다른 프레임워크와 차별화되어 제공하는 의존관계 주입 기능이다.

앞서 말한 것처럼 객체를 직접 생성하는 게 아닌, 외부에서 생성 후 주입 시켜주는 방식이다.

 

// Data 인터페이스
public interface Data {

    public int a();
    public String b();
}

// Data 인터페이스Imp
@Repository
public class DataImp implements Data {

    @Value("123")
    private int a;

    @Value("hello")
    private String b;

    @Override
    public int a() {
        return a;
    }

    @Override
    public String b() {
        return b;
    }
}

// Data 컨트롤러
@RestController
public class DataController {

    @Autowired // 객체 주입
    private Data data;

    @GetMapping("/data1")
    public int data1() {
        return data.a(); // 호출
    }

    @GetMapping("/data2")
    public String data2() {
        return data.b(); // 호출
    }
}

 

위 간단하게 예를 든 코드처럼 new를 사용하여 직접 객체를 생성하지 않고 외부에서 객체를 생성해 주입시켜 주는 방식이다.

 

스프링에서는 객체를 Bean이라고 부르며, 프로젝트가 실행될 때 사용자가 Bean으로 관리하는 객체들의 생성과 소멸에 관련된 작업을 자동적으로 수행해 주는데 객체가 생성되는 곳을 스프링에서는  Bean 컨테이너라고 부른다.

 

- DL

DL(Dependency Lookup)이란 Bean에 접근하기 위해 컨테이너가 제공하는 API를 이용하여 Bean을 Lookup(조회)한다.

한마디로 의존성검색이다.

	<!-- Test1 Bean 등록하기 -->
	<bean id="test1" class="com.folder.bean.Test1" />
	
	<!-- Test2 Bean 등록하기 -->
	<bean id="test2" class="com.folder.bean.Test2">
		<property name="a" value="5" />
		<property name="b" value="오" />
	</bean>
	
	<!-- Test3 Bean 등록하기 -->
	<bean id="test3" class="com.folder.bean.Test3">
		<constructor-arg name="a" value="3" />
		<constructor-arg name="b" value="삼" />
	</bean>

위의 xml파일의 <bean>을 통해 해당 클래스를 검색하여 주입한다.

<bean> 태그의 속성
  • id: bean객체의 고유이름으로, 이를 사용하여 bean에 접근하며 중복되어서는 안 된다.
  • name: bean객체의 별칭
  • class: 생성할 클래스 이름(경로) (bean객체를 주입할 클래스의 이름(경로))
  • constructor-arg: 생성자를 사용해 값을 주입할 때 사용
  • property: Setter를 사용해 값을 주입할 때 사용

 

// Test1 클래스
public class Test1 {
	
	public int test() {
		return 10;
	}
}

// Test2 클래스
public class Test2 {
	
	private int a;
	private String b;
	
	public int getA() {
		return a;
	}
	public void setA(int a) {
		this.a = a;
	}
	public String getB() {
		return b;
	}
	public void setB(String b) {
		this.b = b;
	}

}

// Test3 클래스
public class Test3 {

	private int a;
	private String b;

	public Test3(int a, String b) {
		this.a = a;
		this.b = b;
	}

	public int getA() {
		return a;
	}

	public String getB() {
		return b;
	}

}

Bean Class생성 (값 직접 return, Getter, Setter활용, 메서드 활용)

 

	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("app-context.xml");

		Test1 t1 = context.getBean("test1", Test1.class);
		Test2 t2 = context.getBean("test2", Test2.class);
		Test3 t3 = context.getBean("test3", Test3.class);
        
	}

메인 클래스에서 호출 후 콘솔을 출력하면

각각 bean객체의 값을 출력하는 것을 확인할 수 있다.