스프링을 설정하는 방법
new AnnotationConfigApplicationContext(AppConfig.class)
AnnotationConfigApplicationContext 클래스를 사용하면서 자바 코드로된 설정 정보를 넘기면 된다.
<?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="memberService" class="hello.core.member.MemberServiceImpl" >
<constructor-arg name="memberRepository" ref="memberRepository"/>
</bean>
<bean id="memberRepository" class="hello.core.member.MemoryMemberRepository"/>
<bean id="discountPolich" class="hello.core.discount.RateDiscountPolicy"/>
<bean id="oderService" class="hello.core.order.OrderServiceImpl">
<constructor-arg name="memberRepository" ref="memberRepository"/>
<constructor-arg name="discountPolicy" ref="discountPolich"/>
</bean>
</beans>
⚠️ 생성자의 매개변수와 이름이 다를 경우에는..?
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'oderService' defined in class path resource [appConfig.xml]:
Unsatisfied dependency expressed through constructor parameter 0:
Ambiguous argument values for parameter of type
[hello.core.member.MemberRepository] - did you specify the correct bean references as arguments?
org.springframework.beans.factory.UnsatisfiedDependencyException:
클래스 경로 리소스 [appConfig.xml]에 정의된 이름이 'oderService'인 Bean을 생성하는 중 오류가 발생했습니다.
생성자 매개변수를 통해 표현된 충족되지 않은 종속성 0: [hello.core.member 유형의 매개변수에 대한 모호한 인수 값 .MemberRepository]
- 올바른 Bean 참조를 인수로 지정했습니까?
public class XmlApplication {
@Test
void xmlAppContext() {
ApplicationContext ac = new GenericXmlApplicationContext("appConfig.xml");
MemberService memberService = ac.getBean("memberService", MemberService.class);
assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
}
}
👉 정상 작동
메타정보를 만드는 2가지 방법이 있다.
➡️ 스프링 컨테이너는 이 메타 정보를 기반으로 빈을 생성한다.
역할과 구현을 개념적으로 나눈 것이다.
✍️ BeanDefinition을 만드는 상세 과정
✔️ BeanDefinitiond을 만드는 Reader
✔️ 스프링은 다양한 형태의 설정 정보를 모두 BeanDefinition
으로 추상화해서 사용한다.
public class BeanDefinitionTset {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
/*
BeanClassName: 생성할 빈의 클래스 명(자바 설정 처럼 팩토리 역할의 빈을 사용하면 없음)
factoryBeanName: 팩토리 역할의 빈을 사용할 경우 이름, 예) appConfig
factoryMethodName: 빈을 생성할 팩토리 메서드 지정, 예) memberService
Scope: 싱글톤(기본값)
lazyInit: 스프링 컨테이너를 생성할 때 빈을 생성하는 것이 아니라, 실제 빈을 사용할 때 까지 최대한 생성을 지연
처리 하는지 여부
InitMethodName: 빈을 생성하고, 의존관계를 적용한 뒤에 호출되는 초기화 메서드 명
DestroyMethodName: 빈의 생명주기가 끝나서 제거하기 직전에 호출되는 메서드 명
Constructor arguments, Properties: 의존관계 주입에서 사용한다. (자바 설정 처럼 팩토리 역할의 빈을 사용하면 없음)
*/
@Test
@DisplayName("빈 설정 메타 정보 확인")
void findApplicationBean() {
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);
}
}
}
}
👉 실행화면
beanDefinitionName+ = appConfig beanDefinition = Generic bean:
class [hello.core.AppConfig$$EnhancerBySpringCGLIB$$7fe25ae1]; scope=singleton;
abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true;
primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null;
destroyMethodName=null
화이팅