티스토리 뷰

IoC

'객체의 생성, 생명 주기의 관리 등 객체에 대한 제어권이 바뀌었다.' 라는 의미다.
개발자는 인스턴스 생성부터 인스턴스 관리를 신경써야 했다.
하지만 이를 프레임워크나 다른 주체에 제어권을 위임하는 것을 말한다.

 

컨테이너

컨테이너의 역할은 인스턴스의 생명주기를 관리, 생성된 인스턴스들에게 추가적인 기능을 제공하는 것이다.

 

BeanFactory

IoC 원리를 이용한 스프링 프레임워크의 IoC 컨테이너다.
BeanFactory가 관리하는 객체를 빈(Bean)이라고 부른다.
BeanFactory가 빈을 인스턴스화 하고 DI를 통해 의존성이 주입된 객체로 관리한다.
즉, 애플리케이션 컴포넌트의 중앙 저장소이다.
BeanFactory는 빈 설정 소스로부터 빈 정의를 읽어들이고, 빈을 구성하고 제공한다.

[참고] https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/BeanFactory.html

 

BeanFactory (Spring Framework 5.2.2.RELEASE API)

The root interface for accessing a Spring bean container. This is the basic client view of a bean container; further interfaces such as ListableBeanFactory and ConfigurableBeanFactory are available for specific purposes. This interface is implemented by ob

docs.spring.io

Bean

빈(Bean)은 스프링 IoC 컨테이너가 관리하는 객체이다.
빈은 스코프를 갖고 있는데, 일반 스프링 어플리케이션은 '싱글톤', '프로토타입' 등이 있다.
스프링MVC 웹 어플리케이션에서 빈스코프는 추가적으로 '리퀘스트', '세션', '글로벌 세션' 등이 있다.
기본적인 빈의 스코프는 '싱글톤'으로 생성하여 관리된다.
'싱글톤' 빈은 스프링 컨테이너에서 한번 생성되어 컨테이너가 사라질때 빈도 같이 제거된다.

 

ApplicationContext

ApplicationContext는 BeanFactory기능을 포함하고 있다.

추가적인 기능에는 메시지 소스 처리 기능, 이벤트 발행 기능, 리소스 로딩 기능 등이 추가적으로 제공된다.

[참고] https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/ApplicationContext.html

 

ApplicationContext (Spring Framework 5.2.2.RELEASE API)

Expose AutowireCapableBeanFactory functionality for this context. This is not typically used by application code, except for the purpose of initializing bean instances that live outside of the application context, applying the Spring bean lifecycle (fully

docs.spring.io

 

Bean 설정을 하는 방법들

IoC 컨테이너를 만들기 위해서는 Bean을 설정해야한다.
  • XML을 통해 Bean을 설정하는 방법
  • XML에 Base Package를 설정해서 Component Scan을 하는 방법
  • Java 코드를 활용하여 @Configuration을 이용
  • @Configuration과 @ComponentScan을 이용
  •  

XML을 이용한 Bean 설정 방법

resources에 application.xml을 만든다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="bookService"
          class="goozy.springstudy.BookService">
        <property name="bookRepository" ref="bookRepository"></property>
    </bean>

    <bean id="bookRepository"
          class="goozy.springstudy.BookRepository"/>

</beans>

Application의 main()을 다음과 같이 작성한다.

public class SpringStudyApplication {

    public static void main(String[] args) {
    	// XML설정 파일로 IoC 컨테이너 설정
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");

	// IoC 컨테이너에서 Bean의 이름 검색
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        System.out.println(Arrays.toString(beanDefinitionNames));

	// BookService에 BookRepository가 주입됬는지 확인
        BookService bookService = (BookService) applicationContext.getBean("bookService");
        System.out.println(Objects.nonNull(bookService.bookRepository));
    }
}

일일이 Bean을 등록해줘야 하나?

XML에 Base Package를 설정해서 Component Scan을 하는 방법

그래서 Component Scan을 활용해 @Component가 붙은 클래스를 Bean으로 등록한다.

@Controller, @Service, @Repository 모두 @Component를 확장한 Annotation이다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="goozy.springstudy"/>

</beans>

 

@Configuration을 이용해 Bean 설정하기

BookRepository와 BookService에 달아놓은 모든 Annotation을 지운다.

그리고 ApplicationCofig를 다음과 같이 작성한다.

@Configuration
public class ApplicationConfig {

    @Bean
    public BookRepository bookRepository() {
        return new BookRepository();
    }

    @Bean
    public BookService bookService(BookRepository bookRepository) {
        BookService bookService = new BookService();
        bookService.setBookRepository(bookRepository);
        return new BookService();
    }
}

 

지금은 BookService에 의존성 주입을 설정파일에서 해주고 있다.

그러나 이것도 일일이 이렇게 해주는것도 불편하다.

이럴 때 @Autowired를 붙여주면 알아서 의존성 주입이 된다.

물론 @Autowired에도 필드 주입, 생성자 주입, setter 주입이 존재한다. 각 장단점은 나중에...

@Configuration
public class ApplicationConfig {

    @Bean
    public BookRepository bookRepository() {
        return new BookRepository();
    }

    @Bean
    public BookService bookService() {
        return new BookService();
    }
}

public class BookService {

    @Autowired
    private BookRepository bookRepository;
}

 

@Configuration과 @ComponentScan을 이용

다음 처럼 @Configuration이 붙은 클래스에 @ComponentScan을 붙인다.

@ComponentScan할 Base를 선택하는 방법은 패키지를 직접 문자열로 지정하거나 클래스로 지정하는 방법이 있다.

@Configuration
//@ComponentScan(basePackages = "goozy.springstudy")
@ComponentScan(basePackageClasses = SpringStudyApplication.class) // Type Safe한 방법
public class ApplicationConfig {

}

@SpringBootApplication 이용

스프링 부트가 지원하는 어노테이션이다.

알아서 빈설정을 다 해준다.

// @Configuration, @ComponentScan 확장
// 즉, 이클래스 자체가 빈 설정 파일이고 알아서 해준다.
// SpringBoot가 아주 편하게 해준다.
@SpringBootApplication
public class SpringStudyApplication {

    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringStudyApplication.class);

        System.out.println(Arrays.toString(applicationContext.getBeanDefinitionNames()));

        BookService bookService = (BookService) applicationContext.getBean("bookService");
        System.out.println(Objects.nonNull(bookService.getBookRepository()));
    }
}

 

인프런 백기선님의 강의를 참고하여 학습했습니다.

[연습 코드] https://github.com/hyperpace/spring-study/tree/study/spring-setting-beans/src

 

hyperpace/spring-study

👀 Spring을 사용하면서 학습한 내용을 정리. Contribute to hyperpace/spring-study development by creating an account on GitHub.

github.com

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함