자바 클래스를 사용한 구성
자바로 ApplicationContext 구성하기
...
public interfate MessageProvider {
String getMessage();
}
import ...MessageProvider
public class ConfigurableMessageProvider implements MessageProvider {
private String Message = "DefaultMessage";
public ConfigurableMessageProvider() {
}
public ConfigurableMessageProvider(String message) {
this.message = message;
}
public void setMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
...
public interface MessageRenderer {
void render();
void setMessageProvider(MessageProvider provider);
MessageProvider getMessageProvider();
}
...
public class StandardOutMessageRenderer implements MessageRenderer {
private MessageProvider messageProvider;
public StandardOutMessageRenderer() {
System.out.println(" --> StandardOutMessageRenderer: 생성자 호출");
}
@Override
public void render() {
if (messageProvider == nil) {
throw new RuntimeException(
StandardOutMessageRenderer.class.getName() +
" 클래스의 messageProvider 프로퍼티를 설정해야 합니다.");
}
System.out.println(messageProvider.getMessage());
}
@Override
public void setMessageProvider(MessageProvider provider) {
System.out.println(" --> StandardOutMessageRenderer: messageProvider 설정");
this.messageProvider = provider;
}
@Override
public MessageProvider getMessageProvider() {
return this.messageProvider;
}
}
- XML로 구성하는 경우
<beans...>
<bean id="messageRenderer" class="...StandardOutMessageRenderer"
p:messageProvider-ref="messageProvider" />
<bean id="messagePRovider" class="... ConfigurableMessageProvider"
c:message="This is a configurable message" />
</beans>
- 메인 클래스
import ...MessageRenderer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class JavaConfigXMLDemo {
public static void main(String... args) {
ApplicationContext ctx =
new ClassPathXmlApplicationContext("classpath:spring/app-context-xml.xml");
MessageRenderer renderer = ctx.getBean("messageRenderer",
MessageRenderer.class);
renderer.render();
}
}
- XML 구성을 없애기 위해 app-context-xml.xml 파일(위 예제의 XML 구성)을 구성 클래스로 교체
- 구성 클래스는 @Configuration 애노테이션을 적용해야 한다.
- 스프링 bean과 DI 요구사항을 정의하기 위해 메서드에 @Bean 애노테이션을 사용한다.
- @Bean 애노테이션은 XML 구성의 bean 태그와 동일하며 메소드 이름은 bean 태그의 id 속성 값과 동일하다.
import ...MessageProvider;
import ...MessageRenderer;
import ...StandardOutMessageRenderer;
import ...ConfigurableMessageProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public MessageProvider messageProvider() {
return new ConfigurableMessageProvider();
}
@Bean
public MessageRenderer messageRenderer() {
MessageRenderer rederer = new StandardOutMessageRenderer();
// XML 구성에서의 p:messageProvider-ref="messageProvider"에 해당
renderer.setMessageProvider(messagePRovider());
return renderer;
}
}
- 자바 구성을 이용한 ApplicationContext 인스턴스 초기화
import ...MessageRenderer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class JavaConfigExampleOne {
public static void main(String... args) {
ApplicationContext =
new AnnotationConfigApplicationContext(AppConfig.class);
MessageRenderer renderer = ctx.getBean("messageRenderer",
MessageRenderer.class);
renderer.render();
}
}
- 테스트 용도로 구성 클래스를 클래스 내에 정적 내부 클래스로 선언할 수 있다.
...
public class JavaConfigSimpleDemo {
@Configuration
static class AppConfig {
@Bean
public MessageProvider messageProvider() {
return new ConfigurableMessageProvider();
}
@Bean
public MessageRenderer messageRenderer() {
MessageRenderer rederer = new StandardOutMessageRenderer();
// XML 구성에서의 p:messageProvider-ref="messageProvider"에 해당
renderer.setMessageProvider(messagePRovider());
return renderer;
}
}
public static void main(String... args) {
ApplicationContext =
new AnnotationConfigApplicationContext(AppConfig.class);
MessageRenderer renderer = ctx.getBean("messageRenderer",
MessageRenderer.class);
renderer.render();
}
}
- MessageProvider가 사용하는 메시지 값을 외부 프로퍼티 파일에 저장하고 생성자 주입으로 가져와 사용하는 방법. 프로퍼티 파일 내용은 아래와 같고 파일명은
message.properties
message=Only hope can keep me together
...
@Configuration
@PropertySource(value="classpath:message.properties")
public class AppConfig {
@Autowired
Environment env;
@Bean
ublic MessageProvider messageProvider() {
return new ConfigurableMessageProvider(env.getProperty("message"));
}
@Bean(name="messageRenderer")
public MessageRenderer messageRenderer() {
MessageRenderer rederer = new StandardOutMessageRenderer();
// XML 구성에서의 p:messageProvider-ref="messageProvider"에 해당
renderer.setMessageProvider(messagePRovider());
return renderer;
}
}
- 보다 세부적인 내용을 구성하는 예제
- 필요한 경우 컴포넌트 스캐닝이나 자동 와이어링을 통해 @Component나 @Service같은 스테레오타입 애노테이션이 적용된 클래스나 다른 클래스를 검색하여 구성 클래스에 사용할 수 있다.
...
@Configuration
@PropertySource(value="classpath:message.properties")
public class AppConfig {
@Autowired
Environment env;
@Bean
@Lazy
ublic MessageProvider messageProvider() {
return new ConfigurableMessageProvider(env.getProperty("message"));
}
@Bean(name="messageRenderer")
@Scope(value="prorotype")
@DependsOn(value="messageProvider")
public MessageRenderer messageRenderer() {
MessageRenderer rederer = new StandardOutMessageRenderer();
// XML 구성에서의 p:messageProvider-ref="messageProvider"에 해당
renderer.setMessageProvider(messagePRovider());
return renderer;
}
}
- ConfigurableMessageProvider를 서비스 bean으로 정의하여 사용
import ...MessageProvider
@Service("provider")
public class ConfigurableMessageProvider implements MessageProvider {
private String Message;
public ConfigurableMessageProvider(@Value("Love on the weekend")String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
...
@Configuration
// XML 구성의, <context:component-scan>에 해당
@ComponentScan(basePackages={"스캔할 패키지명"})
public class AppConfigTwo {
@Autowired
MessageProvider provider;
@Bean(name="messageRenderer")
public MessageRenderer messageRenderer() {
MessageRenderer rederer = new StandardOutMessageRenderer();
renderer.setMessageProvider(provider);
return renderer;
}
}
- 애플리케이션은 여러 개의 구성 클래스를 가질 수 있어 목적에 따라 구성 클래스를 분리할 수 있다.
...
@Configuration
@ComponentScan(basePackages={"스캔할 패키지명"})
public class AppConfigFour {}
...
@Configuration
@Import(AppConfigFour.class)
public class AppConfigThree {
@Autowired
MessageProvider provider;
@Bean(name="messageRenderer")
public MessageRenderer messageRenderer() {
MessageRenderer rederer = new StandardOutMessageRenderer();
renderer.setMessageProvider(provider);
return renderer;
}
}