자바 구성 클래스 1

 

자바 클래스를 사용한 구성

자바 클래스를 사용한 구성


자바로 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;
	}
}