IoC(Inversion of Control)란 "제어의 역전" 이라는 의미로, 말 그대로 메소드나 객체의 호출작업을 개발자가 결정하는 것이 아니라, 외부에서 결정되는 것을 의미한다.
간단히 말해 "제어의 흐름을 바꾼다"라고 한다.
객체의 의존성을 역전시켜 객체 간의 결합도를 줄이고 유연한 코드를 작성할 수 있게 하여 가독성 및 코드 중복, 유지 보수를 편하게 할 수 있게 한다.
기존에는 다음과 순서로 객체가 만들어지고 실행되었다.
1.객체 생성
2.의존성 객체 생성 /클래스 내부에서 생성
3.의존성 객체 메소드 호출
하지만, 스프링에서는 다음과 같은 순서로 객체가 만들어지고 실행된다.
1.객체 생성
2.의존성 객체 주입
스스로가 만드는것이 아니라 제어권을 스프링에게 위임하여 스프링이 만들어놓은 객체를 주입한다.
3.의존성 객체 메소드 호출
스프링이 모든 의존성 객체를 스프링이 실행될때 다 만들어주고 필요한곳에 주입시켜줌으로써 Bean들은 싱글턴 패턴의 특징을 가지며,
제어의 흐름을 사용자가 컨트롤 하는 것이 아니라 스프링에게 맡겨 작업을 처리하게 된다.
ApplicationContext 혹은 BeanFactory
ApplicationContext는 BeanFactory를 상속받으므로 둘 다 같은 일을 하는
빈을 만드는 방법은 다양하지만 기본적으로 크게 두가지 방법이 있다.
① Component Scanning
② 빈 설정파일에 직접 빈을 등록
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 "";
}`**
@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