빈(Bean)
빈(Bean)은 스프링 컨테이너에 의해 관리되는 재사용 가능한 소프트웨어 컴포넌트이다.
즉, 스프링 컨테이너가 관리하는 자바 객체를 뜻하며, 하나 이상의 빈(Bean)을 관리한다.
빈은 인스턴스화된 객체를 의미하며, 스프링 컨테이너에 등록된 객체를 스프링 빈이라고 한다.
@Bean 어노테이션을 통해 메서드로부터 반환된 객체를 스프링 컨테이너에 등록한다.
빈은 클래스의 등록 정보, Getter/Setter 메서드를 포함하며, 컨테이너에 사용되는 설정 메타데이터로 생성된다.
설정 메타데이터 : XML 또는 자바 어노테이션, 자바 코드로 표현하며, 컨테이너의 명령과 인스턴스화, 설정, 조립할 객체 등을 정의한다.
빈(Bean) 접근 방법
먼저, ApplicationContext(스프링 컨테이너)를 사용하여 bean을 정의를 읽고 액세스 할 수 있다.
// create and configure beans
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
// retrieve configured instance
PetStoreService service = context.getBean("memberRepository", memberRepository.class);
// use configured instance
List<String> userList = service.getUsernameList();
- getBean() 메서드를 통해 bean의 인스턴스를 가져올 수 있다.
- ApplicationContext 인터페이스는 bean을 가져오는 여러 가지 방법들이 있다.
그러나 실제 응용 프로그램 코드에서는 getBean() 메서드를 통해 호출하지 않는다
BeanDefinition
스프링의 다양한 설정 형식(Java, XML 등)은 BeanDefinition이라는 추상화 덕분에 할 수 있는 것이다.
Bean은 BeanDefinition(빈 설정 메타정보)으로 정의되고, BeanDefinition에 따라 활용하는 방법이 달라진다.
BeanDefinition은 속성에 따라 컨테이너가 Bean을 어떻게 생성하고 관리할지를 결정한다.
@Bean 어노테이션 또는 <bean> 태그당 1개씩 메타 정보가 생성된다.
Spring이 설정 메타정보를 BeanDefinition 인터페이스를 통해 관리하기 때문에 컨테이너 설정을 XML, Java로 할 수 있는 것이다.
스프링 컨테이너는 설정 형식이 XML인지 Java 코드인지 모르며, BeanDefinition만 알면 된다.
BeanDefinition 정보
- BeanClassName : 생성할 빈의 클래스 이름
- factoryBeanName : 팩토리 역할의 빈을 사용할 경우의 이름 (appConfig, … 등)
- factoryMethodName : 빈을 생성할 팩토리 메서드 지정 (memberService, … 등)
- Scope : 싱글톤(기본값)
- lazyInit: 스프링 컨테이너를 생성할 때 빈을 생성하는 것이 아니라, 실제 빈을 사용할 때까지 최대한 생성을 지연 처리하는지 여부
- InitMethodName: 빈을 생성하고, 의존관계를 적용한 뒤에 호출되는 초기화 메서드 명
- DestroyMethodName: 빈의 생명주기가 끝나서 제거하기 직전에 호출되는 메서드 명
- Constructor arguments, Properties: 의존관계 주입에서 사용한다. (자바 설정처럼 팩토리 역할의 빈을 사용하면 없음
빈 설정 메타정보 확인하기
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames ) {
BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);
if (beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {
System.out.println("beanDefinitionName = " + beanDefinitionName + ", beanDefinition = " + beanDefinition);
}
}
빈 이름 조회
- ac.getBeanDefinitionNames(); : 스프링에 등록된 모든 빈 이름을 조회
빈 객체 조회
- ac.getBean(빈이름, 타입) : 빈 인스턴스 조회
- ac.getBean(타입) : 빈 인스턴스 조회(같은 타입의 스프링 빈이 둘 이상이면 예외 발생)
- ac.getBeansOfType(타입) : 해당 타입의 모든 빈 조회
getRole() : 스프링 내부에서 사용하는 빈과 사용자가 등록한 빈을 구분할 수 있다.
BeanDefinition.ROLE_APPLICATION : 일반적으로 사용자가 정의한 빈
BeanDefinition.ROLE_INFRASTRUCTURE : 스프링이 내부에서 사용하는 빈
'프레임워크(Framework) > Spring' 카테고리의 다른 글
[Spring] 스프링 빈 생명주기 콜백 (0) | 2022.11.02 |
---|---|
[Spring] 스프링 빈 스코프(Bean Scope)란 무엇인가? (0) | 2022.11.01 |
[Spring] 스프링 컨테이너(Spring Container)란 무엇인가? (4) | 2022.10.28 |
[Spring Boot] 스프링 부트란 무엇인가? (0) | 2022.10.26 |
[Spring] 스프링 프레임워크(Spring Framework)를 사용하는 이유 (0) | 2022.10.25 |