@Configuration
public class HelloConfig {
@Bean
public Hello hello() {
Hello hello = new Hello();
hello.setName("Spring");
return hello;
}
}public class Hello {
private String name;
public void setName(String name) {
this.name = name;
}
public void sayHello() {
System.out.println("Hello " + name);
}
}위 코드처럼 Hello 빈은 모듈화되어 여러 프로젝트에서 공통적으로 사용되는 인프라 빈이라고 가정한다.
이 정보를 어떻게 가져오고 속성 값을 수정할 수 있는지 알아본다.
@Import
@Configuration
@Import(HelloConfig.class)
public class AppConfig {
}@Import 어노테이션을 통해 설정 정보를 그대로 가져올 수 있다.
하지만 단순히 이렇게 사용하는 것은 설정 정보가 전혀 변경되지 않고 기존 속성 값을 그대로 사용할 때만 가능하다.
여기서는 Hello의 name을 설정할 수 있는 방법이 없다.
Configuration 상속
@Configuration
public class AppConfig extends HelloConfig {
@Bean
public Hello hello() {
Hello hello = new Hello();
hello.setName("My");
return hello;
}
}상속을 통해 @Bean 메소드를 재정의해버리는 방법이다.
하지만 메소드를 통째로 오버라이딩 해야하기에 실수할 확률이 높아 설정이 꼬일수도 있으며 자바에서는 다중 상속이 불가능하기 때문에 필요한 Configuration이 여러 개일 때는 불가능하다는 한계가 있다.
@Enable && ImportAware
스프링에서는 설정 정보를 추가하기 위한 목적으로 @Enable~로 시작하는 어노테이션들을 제공한다.
그리고 이들은 모두 @Import를 메타 어노테이션으로 포함하고 있다.
그 중에서도 @EnableTransactionManagement와 같은 어노테이션은 어노테이션 엘리먼트를 통해 옵션을 지정할 수 있다.
@Enable~자체가 특정 문법은 아니고 관례적인 표현이다.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(HelloConfig.class)
public @interface EnableHello {
String name();
}@Configuration
public class HelloConfig implements ImportAware {
@Bean
public Hello hello() {
Hello hello = new Hello();
hello.setName("Spring");
return hello;
}
// Annotation Element 값을 참조하기 위한 구현
@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
Map<String, Object> elements = importMetadata.getAnnotationAttributes(EnableHello.class.getName());
String name = (String) elements.get("name");
hello().setName(name);
}
}@Configuration
@EnableHello(name="My")
public class AppConfig{
}Configurer
어노테이션에 엘리먼트로 값을 전달하기에는 내용이 너무 많고 복잡한 경우에는 별도의 설정용 인터페이스인 Configurer을 제공할 수 있다.
대표적인 것이 @EnableWebMvc와 함께 사용되는 WebMvcConfigurer이다.
public interface HelloConfigurer {
void configName(Hello hello);
}@Configuration
@EnableHello
public class AppConfig implements HelloConfigurer{
@Override
public void configName(Hello hello) {
hello.setName("My");
}
}@Configuration
public class HelloConfig {
// AppConfig 주입
@Autowired
HelloConfigurer helloConfigurer;
@Bean
public Hello hello() {
Hello hello = new Hello();
hello.setName("Spring");
helloConfigurer.configName(hello);
return hello;
}
}참고
- 이일민, 토비의 스프링 3.1, 에이콘