IoC / Bean

Ioc(Inversion of Control)

  • IoC(Inversion of Control)란 "제어의 역전" 이라는 의미로, 말 그대로 메소드나 객체의 호출작업을 개발자가 결정하는 것이 아니라, 외부에서 결정되는 것을 의미한다.

  • 간단히 말해 "제어의 흐름을 바꾼다"라고 한다.

  • 객체의 의존성을 역전시켜 객체 간의 결합도를 줄이고 유연한 코드를 작성할 수 있게 하여 가독성 및 코드 중복, 유지 보수를 편하게 할 수 있게 한다.

기존에는 다음과 순서로 객체가 만들어지고 실행되었다.

1.객체 생성

2.의존성 객체 생성 /클래스 내부에서 생성

3.의존성 객체 메소드 호출

하지만, 스프링에서는 다음과 같은 순서로 객체가 만들어지고 실행된다.

1.객체 생성

2.의존성 객체 주입
스스로가 만드는것이 아니라 제어권을 스프링에게 위임하여 스프링이 만들어놓은 객체를 주입한다.

3.의존성 객체 메소드 호출

스프링이 모든 의존성 객체를 스프링이 실행될때 다 만들어주고 필요한곳에 주입시켜줌으로써 Bean들은 싱글턴 패턴의 특징을 가지며,

제어의 흐름을 사용자가 컨트롤 하는 것이 아니라 스프링에게 맡겨 작업을 처리하게 된다.

Bean

  • 스프링 IoC 컨테이너가 관리하는 객체들을 Bean 이라고 부릅니다.
  • 스프링은 이러한 Bean들의 의존성을 관리하고, 객체를 만들어 주며, Bean으로 등록을 해 주고, 이렇게 만들어진 것들을 관리합니다. 개발자가 이 부분까지 신경쓰지 않아도, 프레임워크가 알아서 해 주는 것입니다.
  • 그리고 스프링 IoC 컨테이너가 위와 같은 관리를 해 줍니다. 이러한 Bean들을 담고 있는 스프링 IoC 컨테이너는 두 가지 중 하나를 사용합니다.

ApplicationContext 혹은 BeanFactory

ApplicationContext는 BeanFactory를 상속받으므로 둘 다 같은 일을 하는

  • 이러한 스프링에서의 의존성 주입은 반드시 Bean으로 등록된 객체들 끼리만 가능합니다. 스프링 IoC 컨테이너는 Bean으로 등록되지 않은 객체에는 의존성 주입을 해 주지 않습니다.
    - IntelliJ 에서는 Bean 인 경우 아래 사진처럼 왼쪽에 아이콘으로 표시해 줍니다.
    - 위에서 예시를 들었듯, OwnerController 생성자에서 의존성 주입이 일어나고 있습니다.
    - 그러면 OwnerController, OwnerRepository 모두 Bean이어야 할 것입니다.

어떻게 Spring IoC 컨테이너에 빈을 등록할까?

빈을 만드는 방법은 다양하지만 기본적으로 크게 두가지 방법이 있다.

① Component Scanning

② 빈 설정파일에 직접 빈을 등록

1. 자바 어노테이션(Java Annotation)을 사용하는 방법

JAVA에서 Annotation 이라는 기능이 있습니다. 사전상으로는 주석의 의미이지만 Java 에서는 주석 이상의 기능을 가지고 있습니다. Annotation은 자바 소스 코드에 추가하여 사용할 수 있는 메타데이터의 일종입니다. 소스코드에 추가하면 단순 주석의 기능을 하는 것이 아니라 특별한 기능을 사용할 수 있습니다.

Java에서는 @Override, @Deprecated 와 같은 기본적인 Annotation을 제공합니다. 아래의 상속 예제에서는 @Override 를 이용하여 상속임을 명시해줍니다.


**public class Parent { 
    public void doSomething() { 
        System.out.println("This is Parent"); 
    } 
} 

public class Son extends Parent{ 
    @Override 
    public void doSomething() { 
        System.out.println("This is Son"); 
    } 
}**

Spring에서는 여러 가지 Annotation을 사용하지만, Bean을 등록하기 위해서는 @Component Annotation을 사용합니다. @Component Annotation이 등록되어 있는 경우에는 Spring이 Annotation을 확인하고 자체적으로 Bean 으로 등록합니다.

실제 Spring 프로젝트에서 Controller를 등록할 때에는 아래와 같은 Annotation을 사용합니다. 아래의 예시에서 Controller 임을 Spring 에게 알려주기 위하여 @Controller Annotation을 사용했습니다.


**// HelloController.java
@Controller
public class HelloController {
    // Http Get method 의 /hello 경로로 요청이 들어올 때 처리할 Method를 아래와 같이 @GetMapping Annotation을 사용하여 Mapping을 사용할 수 있습니다.
    @GetMapping("hello")
    public String hello(Model model){
        model.addAttribute("data", "This is data!!");
        return "hello";
    }
}**

@Controller Annotation을 intelliJ에서 Ctrl 을 눌러서 이동해보면 아래와 같은 소스를 확인할 수 있습니다. @Controller Annotation에는 @Component Annotation이 있는 것을 확인할 수 있습니다. @Component Annotation 으로 인하여 Spring은 해당 Controller를 Bean 으로 등록합니다.

**`// Controller.java

// -- 일부 생략 --
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {

	/**
	 * The value may indicate a suggestion for a logical component name,
	 * to be turned into a Spring bean in case of an autodetected component.
	 * @return the suggested component name, if any (or empty String otherwise)
	 */
	@AliasFor(annotation = Component.class)
	String value() default "";

}`**

2. Bean Configuration File에 직접 Bean 등록하는 방법

@Configuration과 @Bean Annotation 을 이용하여 Bean을 등록할 수 있습니다. 아래의 예제와 같이 @Configuration을 이용하면 Spring Project 에서의 Configuration 역할을 하는 Class를 지정할 수 있습니다. 해당 File 하위에 Bean 으로 등록하고자 하는 Class에 @Bean Annotation을 사용해주면 간단하게 Bean을 등록할 수 있습니다.


**// Hello.java
@Configuration
public class HelloConfiguration {
    @Bean
    public HelloController sampleController() {
        return new SampleController;
    }
}**

참조
https://velog.io/@gillog/Spring-DIDependency-Injection
https://chanhuiseok.github.io/posts/spring-4/
http://melonicedlatte.com/2021/07/11/232800.html

좋은 웹페이지 즐겨찾기