본문 바로가기

Spring/Spring

(SPRING) IoC 컨테이너 - ApplicationContext와다양한 빈 설정 방법

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

 

spring-boot-starter-web를 추가할 경우 대부분의 기본적인 의존성들이 들어온다.


스프링 설정을 제외한 고전적인 방법의 스프링

1. application.xml 파일 생성 (resources 하위) - code convention [BookService -> bookService]

<bean id="bookService" class="me.choi.springapplicationcontextexerciese.BookService"
        scope="singleton"></bean>

<bean id="bookRepository" class="me.choi.springapplicationcontextexerciese.BookRepository"></bean>
  • property 추가 [name : setter   ref : bean의 id]
<bean id="bookService" class="me.choi.springapplicationcontextexerciese.BookService"
        scope="singleton">
    <property name="bookRepository" ref="bookRepository"></property>
</bean>
  • BookService 
public class BookService {

    BookRepository bookRepository;

    public void setBookRepository(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }
}

2. main 메서드 작성

  • 빈 객체 확인 및 주입 확인
public class DemoApplication {

	public static void main(String[] args) {
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
		String[] beanDefinitionName = applicationContext.getBeanDefinitionNames();
		System.out.println(Arrays.toString(beanDefinitionName));

		BookService bookService = (BookService) applicationContext.getBean("bookService");
		System.out.println(bookService.bookRepository != null);
	}
}

결과

이 방법의 단점은 일일이 이렇게 빈으로 등록하는 게 굉장히 번거롭다는 것이다.


Component-Scan의 등장 (Spring 2.5부터 가능)

<context:component-scan base-package="me.choi.springapplicationcontextexerciese"/>

해당 코드의 의미 : 나는 이 패키지부터 빈을 스캐닝을 해서 등록을 하겠다.

 

어노테이션의 사용

@Repository
public class BookRepository {
}
@Service
public class BookService {

    BookRepository bookRepository;

    public void setBookRepository(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }
}

 

@Autowired의 사용 (의존성이 주입된다.)

@Service
public class BookService {
    
    @Autowired
    BookRepository bookRepository;

    public void setBookRepository(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }
}

실행결과

빈 설정 파일을 xml이 아닌 java로 만들 수 없을까?


Java 설정 파일의 등장 (일일이 Bean을 등록)

어노테이션을 이용한 빈 생성 (component-scan은 필요 없다.)

@Configuration : 해당 파일은 설정 파일 임을 명시해주는 어노테이션

@Configuration
public class ApplicationConfig {

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

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

        return bookService;
    }
}

메서드 파라미터로 주입 (BookRepository가 bean으로 등록되어있다는 전제)

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

    return bookService;
}

메인 메서드 작성

public class DemoApplication {

	public static void main(String[] args) {
		//해당 클래스르 빈 설정 파일로 사용
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ApplicationConfig.class);

		String[] beanDefinitionName = applicationContext.getBeanDefinitionNames();
		System.out.println(Arrays.toString(beanDefinitionName));

		BookService bookService = (BookService) applicationContext.getBean("bookService");
		System.out.println(bookService.bookRepository != null);
	}
}

실행결과

@Autowired 사용

@Bean
public BookService bookService(BookRepository bookRepository) {
    //@Autowired를 사용하는 방법
    return new BookService();
}
public class BookService {
    @Autowired
    BookRepository bookRepository;

    public void setBookRepository(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }
}

setter를 썻을때는 @Autowired를 쓸 수 있는 장점이 생긴다.

 

일일이 bean으로 등록하지 않는 편한 방법이 없을까?


@ComponentScan의 등장 

@ComponentScan(basePackageClasses = 클래스명. class) - 해당 클래스가 위치한 곳부터 component scan을 하시오.

  • 애노테이션이 붙어있는 클래스를 찾아 Bean으로 등록
@Configuration
@ComponentScan(basePackageClasses = DemoApplication.class)
public class ApplicationConfig {


}

@Service 추가

@Service
public class BookService {
    @Autowired
    BookRepository bookRepository;

    public void setBookRepository(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }
}

@Repository 추가

@Repository
public class BookRepository {
}

https://jwdeveloper.tistory.com/108

 

(SpringBoot) SpringBoot 자동설정

@EnableAutoConfiguration @SpringBootApplication public class SpringbootgettingstartedApplication { public static void main(String[] args) { SpringApplication.run(SpringbootgettingstartedApplication..

jwdeveloper.tistory.com


끝판왕 @SpringBootApplication 

@SpringBootApplication
public class DemoApplication {

	public static void main(String[] args) {

	}
}

이이 Configuration이 붙어있다. 

componentScan 또한 있다.

ApplicationConfig 도 이제 필요 없다.


정리

스프링 IoC 컨테이너의 역할

  • 빈 인스턴스 생성
  • 의존 관계 설정
  • 빈 제공

AppcliationContext

  • ClassPathXmlApplicationContext (XML)
  • AnnotationConfigApplicationContext (Java)

코드 참고

https://github.com/mike6321/Spring/tree/master/Spring/springapplicationcontextexerciese

 

mike6321/Spring

Contribute to mike6321/Spring development by creating an account on GitHub.

github.com