-
스프링 IoC 컨테이너와 빈의 생성Spring 2023. 6. 26. 21:32
스프링 프레임워크에서 스프링 IoC 컨테이너에 의해서 관리되는 객체를 빈(Bean)이라고 합니다. 그리고 컨테이너는 빈을 생성할 때 의존성을 주입합니다.
org.springframework.context.ApplicationContext 인터페이스를 구현해서 Spring IoC 컨테이너를 생성할 수 있습니다. 컨테이너는 configuration metadata(XML 또는 애노테이션 기반의 자바 코드를 통해 나타냄.)를 읽어서 빈의 인스턴스화, 구성, 그리고 조립을 담당합니다.
애노테이션(Annotation) 기반의 컨테이너 생성
AppConfig.java
@Configuration public class AppConfig { @Bean public MyService myService(MyRepository myRepository) { return new MyServiceImpl(myRepository()) } @Bean public MyRepository myRepository() { return new MyJdbcRepository(); } }
- 스프링 컨테이너가 스프링 빈을 등록하고 알아서 의존 관계를 설정(주입)함.
- 메서드 이름이 빈 이름이 됨.
MyApp.java
public class MyApp { public static void main(String[] args) { ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class); MyService myService = ac.getBean("myService", MyService.class); // Use myService ... } }
스프링 컨테이너에 @Configuration 클래스를 등록해서 스프링 빈을 등록하고 획득할 수 있음.
XML 기반의 컨테이너 생성
appConfig.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 https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="myService" class="my.package.service.MyServiceImpl"> <!-- 설정 --> <constructor-arg name="myRepository" ref="myRepository"> </bean> <bean id="myRepository" class="my.package.repository.MyJdbcRepository"></bean> </beans>
MyApp.java
public class MyApp { public static void main(String[] args) { // 파일 경로 기반 ApplicationContext ac1 = new GenericXmlApplicationContext("appConfig.xml"); // 클래스 패스 기반 ApplicationContext ac2 = new ClassPathApplicationContext(new String[] {"a.xml", "b.xml"}) MyService myService = ac1.getBean("myService", MyService.class); // Use myService ... } }
컴포넌트 스캔(Component Scan)을 사용하여 컨테이너 생성
설정 정보가 없어도 @Component( + @Component meta-annotated)가 명시된 클래스를 찾아서 자동으로 스프링 빈을 등록해주는 기능. 빈의 이름은 클래스 이름에 lowerCamelCase를 적용.
컴포넌트 스캔을 사용하면, 설정 클래스에 @Bean으로 일일이 메서드를 정의하여 빈을 등록하지 않아도 되며, 그럴 때 @Autowired를 사용해서 자동으로 의존 관계를 주입해야 함.
@Component meta-annotated(각 애노테이션.java 정의를 보면, @Component가 명시되어 있음.)
- @Controller
- @Service
- @Repository
- Configuration
AppConfig.java
@Configuration @ComponentScan public class AppConfig { // 모든 빈을 컴포넌트 스캔으로 등록할 것이라면, @Bean으로 등록하지 않아도 됨. private final MyBean mybean; @Autowired // 생성자가 하나인 경우, 애노테이션 생략 가능 public AppConfig(MyBean myBean) { this.myBean = myBean; } // @Bean definition using "myBean" }
basePackage를 지정해주지 않으면, @ComponentScan 클래스 파일이 있는 패키지를 기준으로 하위 패키지를 모두 탐색해서 @Component를 찾아냄. 따라서 설정 클래스 파일을 프로젝트의 최상단에 두고 사용함.
MyServiceImpl.java
@Component public class MyServiceImpl implements MyService { private final MyRepository myRepository; @Autowired public MyServiceImpl(MyRepository myRepository) { this.myRepository = myRepository; } }
이전의 예시와 동일하게 AnnotationConfigApplicationContext를 생성해서 설정 클래스 등록하고 사용
문서
spring document
(https://docs.spring.io/spring-framework/reference/core/beans.html)
'Spring' 카테고리의 다른 글
[Spring] 전자정부프레임워크 crypto를 활용한 암호화 (0) 2024.06.17 [Spring] @RequestBody와 @ResponseBody를 사용해 JSON 형식의 데이터 주고받기 (0) 2023.08.31