Spring @Autowired 사용법 이해 라는 질문에 따라 Spring Wireing 의 다른 옵션 인 @Configuration
클래스에 대한 완전한 지식 기반을 만들고 싶었습니다 .
다음과 같은 스프링 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-3.0.xsd">
<import resource="another-application-context.xml"/>
<bean id="someBean" class="stack.overflow.spring.configuration.SomeClassImpl">
<constructor-arg value="${some.interesting.property}" />
</bean>
<bean id="anotherBean" class="stack.overflow.spring.configuration.AnotherClassImpl">
<constructor-arg ref="someBean"/>
<constructor-arg ref="beanFromSomewhereElse"/>
</bean>
</beans>
@Configuration
대신 어떻게 사용할 수 있습니까? 코드 자체에 영향을 미칩니 까?
답변
XML 마이그레이션 @Configuration
@Configuration
몇 단계 만 거치면 xml을로 마이그레이션 할 수 있습니다 .
-
@Configuration
주석이 달린 클래스를 만듭니다 .@Configuration public class MyApplicationContext { }
-
각
<bean>
태그에 대해 다음 과@Bean
같이 주석이 달린 메소드를 만듭니다 .@Configuration public class MyApplicationContext { @Bean(name = "someBean") public SomeClass getSomeClass() { return new SomeClassImpl(someInterestingProperty); // We still need to inject someInterestingProperty } @Bean(name = "anotherBean") public AnotherClass getAnotherClass() { return new AnotherClassImpl(getSomeClass(), beanFromSomewhereElse); // We still need to inject beanFromSomewhereElse } }
-
수입하기 위해
beanFromSomewhereElse
우리는 정의를 가져와야합니다. XML로 정의 할 수 있으며 다음을 사용할 것입니다@ImportResource
.@ImportResource("another-application-context.xml") @Configuration public class MyApplicationContext { ... }
Bean이 다른
@Configuration
클래스에 정의되어 있으면@Import
주석을 사용할 수 있습니다 .@Import(OtherConfiguration.class) @Configuration public class MyApplicationContext { ... }
-
다른 XML이나
@Configuration
클래스를 가져온 후에는@Configuration
다음과 같이 클래스에 개인 멤버를 선언하여 컨텍스트에서 선언 한 Bean을 사용할 수 있습니다 .@Autowired @Qualifier(value = "beanFromSomewhereElse") private final StrangeBean beanFromSomewhereElse;
또는 이에 의존하는 Bean을 정의하는 메소드에서 다음과 같이 매개 변수로 직접
beanFromSomewhereElse
사용@Qualifier
합니다.@Bean(name = "anotherBean") public AnotherClass getAnotherClass(@Qualifier (value = "beanFromSomewhereElse") final StrangeBean beanFromSomewhereElse) { return new AnotherClassImpl(getSomeClass(), beanFromSomewhereElse); }
-
속성 가져 오기는 다른 xml 또는
@Configuration
클래스 에서 bean을 가져 오는 것과 매우 유사합니다 . 사용하는 대신 다음과 같이 속성과 함께@Qualifier
사용@Value
합니다.@Autowired @Value("${some.interesting.property}") private final String someInterestingProperty;
이것은 SpEL 표현식 에서도 사용할 수 있습니다 .
-
Spring이 이러한 클래스를 Bean 컨테이너로 취급 할 수 있도록하려면이 태그를 컨텍스트에 넣어 메인 xml에 표시해야합니다.
<context:annotation-config/>
이제
@Configuration
간단한 빈을 만드는 것과 똑같은 클래스를 가져올 수 있습니다 .<bean class="some.package.MyApplicationContext"/>
스프링 XML을 모두 피하는 방법이 있지만이 답변의 범위에 포함되지 않습니다. 이 옵션 중 하나는 내 답변을 기반으로하는 내 블로그 게시물 에서 찾을 수 있습니다 .
이 방법 사용의 장단점
기본적으로 다음과 같은 몇 가지 장점으로 인해 XML을 사용하는 것보다 빈을 선언하는이 방법이 훨씬 더 편합니다.
- 오타 –
@Configuration
클래스가 컴파일되고 오타는 컴파일을 허용하지 않습니다. - 빠른 실패 (컴파일 시간) -빈을 주입하는 것을 잊은 경우 XML과 같이 런타임이 아닌 컴파일 시간에 실패합니다.
- IDE에서 더 쉽게 탐색 -종속성 트리를 이해하기 위해 Bean 생성자 간.
- 구성 시작을 쉽게 디버그 가능
단점은 내가보기에 그리 많지 않지만 몇 가지 생각할 수 있습니다.
- 남용 -코드는 XML보다 남용하기 쉽습니다.
- XML을 사용하면 컴파일 타임에는 사용할 수 없지만 런타임에는 제공되는 클래스를 기반으로 종속성을 정의 할 수 있습니다.
@Configuration
클래스를 사용하면 컴파일 타임에 사용할 수있는 클래스가 있어야합니다. 일반적으로 문제가되지 않지만 문제가있을 수있는 경우가 있습니다.
결론 : 애플리케이션 컨텍스트에서 XML @Configuration
과 주석 을 결합하는 것은 완벽합니다 . Spring은 빈이 선언 된 메소드에 대해 신경 쓰지 않습니다.