Spring IoC
IoC = inversion of control : 제어권의 역전
일반적인 경우 의존성에 대한 제어권을 자기 자신이 가진다. 의존관계는 간단히 말해 new 라는 키워드를 통해 생성된다.
public class Sample {
private Samsung samsung = new Samsung();
}
의존성 역전(Inversion of Control)
-Ioc란 inversion of Control의 약어로, 객체의 의존성을 역전시켜 객체 간의 결합도를 줄이고 유연한 코드를 작성 하게하여 가독성 및 코드의 중복, 유지보수를 편하게 할 수 있게 한다.
SampleTest 라는 클래스에서 Samsung 객체를 생성한뒤 Sample 클래스의 생성자로 주입시켜준다.
여기서 Sample이 직접 Samsung을 생성하는 것이 아니라 생성자로 주입받는다.
class Sample {
private Samsung samsung;
public Sample(Samsung samsung){
this.samsung = samsung;
}
}
class SampleTest{
Samsung samsung = new Samsung();
Sample sample = new Sample(samsung);
}
이처럼 첫 번째 예시에서는 Samsung의 제어권이 Sample에게 있었다면 , 두번째 예시는 Sample에게 있는것이 아니라
SampleTest에게 있다. 의존성을 역전시켜 제어권을 직접 갖지 않는것 을 IoC라고 하며, 의존성을 외부에서 주입시켜 주는것을 DI라고 한다.
이것을 사용하는 이유는?
스프링에서 Spring 컨테이너, IoC 컨테이너라는 개념을 사용한다. 컨테이너는 보통 인스턴스의 생명주기를 관리하며, 생성된 인스턴스들에게 추가적인 기능을 제공하도록 하는 것이라고 할 수있다.
컨테이너란 내가 작성한 코드의 처리과정을 위임받은 독립적인 존재라고 생각하면 된다.
컨테이너는 적절한 설정만 되어있다면 누구의 도움 없이도 프로그래머가 작성한 코드를 스스로 참조한 뒤 알아서 객체의 생성과 소멸을 컨트롤해준다.
스프링 컨테이너는 스프링 프레임워크의 핵심부에 위치하며, 종속객체 주입을 이용하여 애플리케이션을 구성하는 컴포넌트들을 관리한다. 이때 스프링 컨테이너에서 생성되는 객체를 Bean이라고 한다.
Bean
Bean은 Spring Bean Container에 존재하는 객체를 말한다. Bean Container는 의존성 주입을 통해 Bean 객체를 사용할 수 있도록 해준다. Bean은 보통 싱글턴으로 존재한다. Beans는 우리가 컨테이너에 공급하는 설정 메타 데이터(xml 파일)에 의해 생성된다.
스프링 컨테이너에서 Bean 생성 원리
스프링부트 가장 상위 클래스의 @SpringBootApplication
@SpringBootApplication
public class SpringPracApplication {
public static void main(String[] args) {
SpringApplication.run(SpringPracApplication.class, args);
}
}
하나 이상의 @Bean 메소드를 선언하고 자동 구성 및 구성 요소 스캐닝을 트리거하는 구성 클래스를 나타냅니다.
@Configuration, @EnableAutoConfiguration 및 @ComponentScan을 선언하는 것과 동일한 편리한 주석입니다.
@ComponentScan은 @Component 어노테이션이나 stereotype(@Service, @Controller, @Repository 등)
어노테이션이 부여된 class를 찾아 자동으로 Bean으로 등록해주는 역할을 한다. 여기서 @ComponentScan을 해주는
범위가 해당 어노테이션이 붙은 위치보다 하위의 class들만 스캔해주기 때문에 @SpringBootApplication의 위치가
가장 상위 위치에 있어야 한다.
@Service, @Controller, @Repository 등의 어노테이션들도 command 키를 누른 후 클릭해보면
@Component가 있는 것을 확인할 수 있다.
원래 Domain-Driven Design(Evans, 2003)에 의해 "캡슐화된 상태 없이 모델에서 단독으로 독립된
인터페이스로 제공되는 작업"으로 정의된 "서비스"임을 나타냅니다.
클래스가 "Business Service Facade"(Core J2EE 패턴 의미에서) 또는 이와 유사한 것임을 나타낼 수도
있습니다. 이 주석은 범용 고정 관념이며 개별 팀은 의미 체계를 좁히고 적절하게 사용할 수 있습니다.
이 주석은 @Component의 전문화 역할을 하여 구현 클래스가 클래스 경로 스캔을 통해 자동 감지되도록 합니다.
"컨트롤러"(예: 웹 컨트롤러)임을 나타냅니다.
이 주석은 @Component의 전문화 역할을 하여 구현 클래스가 클래스 경로 스캔을 통해 자동 감지되도록 합니다.
일반적으로 org.springframework.web.bind.annotation.RequestMapping 주석을 기반으로 하는
주석 처리기 메서드와 함께 사용됩니다.
원래 Domain-Driven Design(Evans, 2003)에 의해 "객체 컬렉션을 에뮬레이트하는
저장, 검색 및 검색 동작을 캡슐화하기 위한 메커니즘"으로 정의된 "리포지토리"임을 나타냅니다.
"데이터 액세스 개체"와 같은 기존 Java EE 패턴을 구현하는 팀도 이 스테레오타입을 DAO 클래스에 적용할 수
있지만 그렇게 하기 전에 데이터 액세스 개체와 DDD 스타일 리포지토리 간의 차이점을 이해하는데 주의를
기울여야 합니다. 이 주석은 범용 고정 관념이며 개별 팀은 의미 체계를 좁히고 적절하게 사용할 수 있습니다.
기존에 자바 코드를 작성시에 인스턴스를 생성한다면 항상 new를 붙이고 새로 생성해줬었다.
하지만 스프링에서는 스프링 컨테이너가 싱글턴 패턴을 사용해 Bean으로 객체를 관리한다.
Service나 Controller 같은 한번만 호출해도 되는 객체들은 Bean으로 등록하여 관리한다면
결합도가 낮아져 유지보수에 용이할 것이다.